我有一个 C++ dll,它定义了一个结构和一个 dll 调用,如下所示:
typedef const char* FString;
typedef struct {
FString version;
FString build_no;
FString build_type;
FString build_date;
FString build_info;
FString comment;
} FVersionInfo;
extern "C" FAPI_EXPORT FVersionInfo CALLINGCONV fGetVersion(void);
在 c# 端我使用动态加载:
[DllImport("kernel32.dll", EntryPoint = "LoadLibrary")]
static extern int LoadLibrary(
[MarshalAs(UnmanagedType.LPStr)] string lpLibFileName);
[DllImport("kernel32.dll", EntryPoint = "GetProcAddress")]
static extern IntPtr GetProcAddress(int hModule,
[MarshalAs(UnmanagedType.LPStr)] string lpProcName);
[DllImport("kernel32.dll", EntryPoint = "FreeLibrary")]
static extern bool FreeLibrary(int hModule);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct FVersionInfo
{
public string Version;
public string Build_No;
public string Build_Type;
public string Build_Date;
public string Build_Info;
public string Comment;
}
[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Ansi)]
public delegate FVersionInfo fGetVersion();
public fGetVersion GetVersion;
FHandle = LoadLibrary(@pName);
IntPtr intPtr;
intPtr = GetProcAddress(FHandle, "fGetVersion");
GetVersion = (fGetVersion)Marshal.GetDelegateForFunctionPointer(intPtr, typeof(fGetVersion));
调用代码应该是:
FVersionInfo version = new FVersionInfo();
version = GetVersion();
我的第一个问题是,我在 c# 加载部分中调用 Marshal.GetDelegateForFunctionPointer 时成为“System.Runtime.InteropServices.MarshalDirectiveException”。
然后我使用 IntPtr 作为结构返回参数进行了测试,如下所示:
[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Ansi)]
public delegate IntPtr fGetVersion();
所以我让 Marshal.GetDelegateForFunctionPointer 工作,但后来我遇到了同样的编组问题:
IntPtr DllValue = new IntPtr();
FVersionInfo version = new FVersionInfo();
DllValue = fGetVersion();
Marshal.PtrToStructure(DllValue, FVersionInfo);
在这里,它在 fGetVersion() 调用“托管调试助手'PInvokeStackImbalance'”时崩溃。我认为这意味着堆栈已损坏(不平衡)。
我已经测试了结构定义的许多变体,但没有结果。
欢迎任何想法或建议!