gpt4 book ai didi

c# - 将 c# 结构传递给非托管 C++ DLL 时出现 SafeArrayTypeMismatchException

转载 作者:搜寻专家 更新时间:2023-10-31 01:47:23 24 4
gpt4 key购买 nike

大家好,我是 C# 和 C++ 编程新手,正在尝试在 C# 项目 (.NET 3.5) 中使用非托管 C++ dll。我被这个错误困住了:

System.Runtime.InteropServices.SafeArrayTypeMismatchException:指定的数组不是预期的类型。

这是DLL的头文件

#ifdef FUNCTIONLIB_EXPORTS
#define FUNCTIONLIB_API __declspec(dllexport)
#else
#define FUNCTIONLIB_API __declspec(dllimport)
#endif
typedef struct _FunctionOpt
{
char UserName[32];
char Password[32];
char ServerIP[128];
int ServerPort;
int Index;
char TargetSubChannel;
long Timeout;
char Filepath[256];
bool isFirst;
DWORD SyncTime;
char *pOutBuf;
int OutBufSize;
unsigned short OutImgResW;
unsigned short OutImgResH;

}STFUNCTIONOPT, *PSTFUNCTIONOPT;

FUNCTIONLIB_API int FunctionLib_Snapshot( PSTFUNCTIONOPT pstFunctionOpt );

我无权访问 C++ 代码,因此我只能更改以下 C# 代码。我的相关代码如下:

    public unsafe struct PSTFUNCTIONOPT            
{
public char[] UserName;
public char[] Password;
public char[] ServerIP;
public int ServerPort;
public int Index;
public char TargetSubChannel;
public long Timeout;
public char[] Filepath;
public bool isFirst;
public uint SyncTime;
public char *pOutBuf; // example C++ usage: myStruct.pOutBuf = (char*)malloc(1920 * 1080 * 3);
public int OutBufSize;
public ushort OutImgResW;
public ushort OutImgResH;
}

// need to use dumpbin to get entrypoint name due to c++ mangling
[DllImport(@"C:\Location\To\Project\bin\FunctionLibLib.dll", EntryPoint = "?FunctionLib_Snapshot@@YAHPAU_FunctionOpt@@@Z")]
public static extern int FunctionLib_Snapshot(PSTFUNCTIONOPT pstFunctionOpt);

public unsafe int FunctionLib_Run()
{
PSTFUNCTIONOPT stFunctionOpt = new PSTFUNCTIONOPT();

stFunctionOpt.UserName = ("uname").ToCharArray();
stFunctionOpt.Password = ("pword").ToCharArray();
stFunctionOpt.ServerIP = ("192.168.1.1").ToCharArray();
stFunctionOpt.ServerPort = 80;
stFunctionOpt.Index = 255;
stFunctionOpt.Timeout = 15000;
stFunctionOpt.Filepath = ("c:\\temp\\test.jpg").ToCharArray();
stFunctionOpt.isFirst = true;
stFunctionOpt.SyncTime = 0;
//stFunctionOpt.pOutBuf = new char*[10000]; // not sure how to do this yet
stFunctionOpt.OutBufSize = 10000;

// get result from DLL
return FunctionLib_Snapshot(stFunctionOpt);
}

如何正确地将结构传递给这个非托管 DLL?该错误似乎很简单,但我无法缩小问题范围。感谢您的帮助!

最佳答案

几个问题:

    public char[] UserName;

需要将其编码为嵌入式字符串:

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string UserName;

对像这样声明的其他字段重复此操作。

    public char *pOutBuf;   // example C++ usage: myStruct.pOutBuf = (char*)malloc(1920 * 1080 * 3);

尚不清楚是 C++ 函数分配了该缓冲区还是客户端代码应该这样做。如果是前者,那么你有一个大问题,你不能调用 free() 函数再次释放缓冲区。您唯一的希望是您的 C# 代码应该分配它,这并非不可能。在这种情况下是:

    public byte[] pOutBuf;
...
stFunctionOpt.pOutBuf = new byte[10000];
stFunctionOpt.OutBufSize = stFunctionOpt.pOutBuf.Length;

pinvoke 声明错误:

[DllImport(@"C:\Location\To\Project\bin\FunctionLibLib.dll", EntryPoint = "?FunctionLib_Snapshot@@YAHPAU_FunctionOpt@@@Z")]
public static extern int FunctionLib_Snapshot(PSTFUNCTIONOPT pstFunctionOpt);

参数是 ref PSTFUNCTIONOPT pstFunctionOpt。请从结构名称中删除 P,它不是指针类型。避免对 DLL 的路径进行硬编码,这不会在您用户的计算机上运行。只需确保您的构建输出目录中有 DLL 的拷贝即可。

关于c# - 将 c# 结构传递给非托管 C++ DLL 时出现 SafeArrayTypeMismatchException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19218066/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com