2013-06-06 78 views
1

我的C#項目必須引用一個C++中的DLL結構的dll,如何從C調用一個函數在結構++由C#

調用setConfig()是我的目標,頭部看起來像

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; 
     ... 
    } 
} 

而且C#看起來像

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"); 
     } 
    } 
} 

在最後一行錯誤是「嘗試讀取或寫入受保護的內存。這通常是指示其他內存已損壞。」

如何通過C#調用SetConfig()?

+0

C++中的結構體與類沒有區別,它只有默認情況下公共的成員。你不能調用C++類或struct的實例方法,你不能得到正確的* this *指針。您必須使用C++/CLI語言編寫包裝器。 –

+0

你說得對,最後我寫了一個C++包裝器。這是一個真正過時的技術 – user2458323

回答

1

在這種調用setConfig是結構的(純)虛memberfunction,所以調用約定應該是thiscall和函數指針不喜歡在你的C#代碼的結構內舉行,但在它的虛函數表。

C++代碼中結構的聲明可能更像C#中的接口,而不是C#中的結構。

對不起,我不能給出一個完整的答案,但我希望這會指出你在正確的方向。