我的 C# 项目必须引用 C++ dll,
struct 中的 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");
}
}
}
最后一行的错误是“试图读取或写入 protected 内存。这通常表明其他内存已损坏。”
C#如何调用SetConfig()?
最佳答案
在这个 SetConfig 中是结构的(纯)虚拟成员函数,因此调用约定应该是 thiscall,函数指针不保存在结构中就像在您的 C# 代码中一样,但在它的 vtable 中。
C++ 代码中结构的声明可能更像是 C# 中的接口(interface)而不是 C# 中的结构。
很抱歉,我无法给出完整的答案,但我希望这能为您指明正确的方向。
关于c# - 如何通过 C# 从 C++ dll 调用结构中的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16956820/