我有一个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);
这里,它在使用“托管调试助手'PInvokeStackImbalance'的fGetVersion()调用时崩溃”。我认为这意味着,堆栈已损坏(不平衡)。
我已经测试了结构定义的许多变体,但没有结果。
欢迎任何想法或建议!
感谢方向,但我找到了可行的解决方案:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct FVersionInfo { public IntPtr Version; public IntPtr Build_No; public IntPtr Build_Type; public IntPtr Build_Date; public IntPtr Build_Info; public IntPtr Comment; }
所以我顺利通过了Marshal.GetDelegateForFunctionPointer
。
我将使用代码更改为:
GF.FVersionInfo vi = new GF.FVersionInfo(); vi = gf.GetVersion();
string MyVersion = Marshal.PtrToStringAnsi(VersionInfos.Version);
[抱歉,我想问一个问题。如果在dll c ++中:
typedef struct {
WORD num
} FVersionInfoChild
typedef struct {
FString version;
FVersionInfoChild arrayStruct[8];
} FVersionInfo
然后,在C#中如何获取Struct数组?