1

My C# project have to refer a C++ dll,

SetConfig() in struct is my target, the head look like

extern "C"
{
    int HSAPI GetSDKVersion();
    IHsFutuComm* HSAPI NewFuCommObj(void* lpReserved = NULL);

    struct IHsFutuComm:public IHSKnown
    {
        virtual int HSAPI SetConfig(const char* szSection,const char* szName,const char* szVal) = 0;
        ...
    }
}

And C# look like

class Program
{
    [DllImport("kernel32.dll")]
    private static extern IntPtr LoadLibrary(string dllToLoad);

    [DllImport("kernel32.dll")]
    public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);

    public delegate Int32 GetSDKVersion();
    public delegate IntPtr NewFuCommObj(IntPtr lpReserved);

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
    public struct IHsFutuComm
    {
        [MarshalAs(UnmanagedType.FunctionPtr)]
        public SetConfig pSetConfig;
    }

    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    public delegate Int32 SetConfig(string szSection, string szName, string szVal);

    static void Main(string[] args)
    {
        var pDll = LoadLibrary("HsFutuSDK.dll");
        var pGetSDKVersion = GetProcAddress(pDll, "GetSDKVersion");
        var dGetSDKVersion = (GetSDKVersion)Marshal.GetDelegateForFunctionPointer(pGetSDKVersion, typeof(GetSDKVersion));
        var sdkVersion = dGetSDKVersion();
        if (sdkVersion == 0x10000019)
        {
            var pNewFuCommObj = GetProcAddress(pDll, "NewFuCommObj");
            var dNewFuCommObj = Marshal.GetDelegateForFunctionPointer(pNewFuCommObj, typeof(NewFuCommObj)) as NewFuCommObj;
            var pIHsFutuComm = dNewFuCommObj(IntPtr.Zero);
            var IHsFutuComm1 = (IHsFutuComm)Marshal.PtrToStructure(pIHsFutuComm, typeof(IHsFutuComm));

            //error here
            var re = IHsFutuComm1.pSetConfig("futu", "server", "127.0.0.1:2800");
        }
    }
}

The error at last line is "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."

How to call SetConfig() by C# ?

2
  • A struct in C++ is indistinguishable from a class, it merely has members that are public by default. You cannot pinvoke instance methods of a C++ class, or struct, you can't get the required this pointer correct. You must write a wrapper in the C++/CLI language. Commented Jun 6, 2013 at 13:27
  • You are right, finally I write a C++ wrapper. This is a truly outdated technology Commented Jun 13, 2013 at 0:28

1 Answer 1

1

In this SetConfig is a (pure) virtual memberfunction of the struct, so the calling convention should be a thiscall, and the function pointer is not held inside the struct like in your C# code, but in it's vtable.

The declaration of the struct in the c++ code is probably more like an interface in C# than a struct in C#.

I'm sorry I can't give a complete answer, but I hope this will point you in the right direction.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.