我有一个定义了结构体和dll调用的C ++ 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’”导致程序崩溃。我认为这意味着堆栈已被破坏(不平衡)。
我已经尝试了许多结构定义的变体,但没有结果。
欢迎任何想法或建议!