我正在尝试将一个C DLL导入到我的C#项目中。.h代码如下所示:
_declspec(dllexport) LRESULT CALLBACK SensFindDeviceW(LONG n, LPWSTR pwszMask, PSENSDEVICEW pDevice);_SENSDEVICEW结构:
typedef struct _SENSDEVICEW
{
WCHAR szSerialNo[32];
WCHAR szDeviceID[32];
LONG nIndex;
} SENSDEVICEW, * PSENSDEVICEW;因此,到目前为止,我在C#中所做的工作是使用DLLImport:
[DllImport("dll/UFTAccess.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
static extern unsafe long SensFindDeviceW(long n, String pszMask, SENSDEVICEW pDevice);定义结构:
[StructLayout(LayoutKind.Sequential)]
unsafe struct SENSDEVICEW
{
public char[] szSerialNo;
public char[] szDeviceID;
public long nIndex;
}并试图在一种方法中使用它:
SENSDEVICEW myDevice = new SENSDEVICEW();
myDevice.szSerialNo = new char[32];
myDevice.szDeviceID = new char[32];
long test = SensFindDeviceW(1, "", myDevice);有了这个get System.Runtime.InteropServices.SafeArrayTypeMismatchException.
如果不初始化数组,则会出现堆栈不平衡错误。
我已经尝试过使用stringbuilder (它不起作用)并对char-数组进行编组,如下所示:
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
string szSerialNo;但它会导致堆栈不平衡。
也许你们中的任何人都知道我还能尝试让dll工作吗?
发布于 2014-03-07 10:05:36
我看到以下问题:
LRESULT是指针大小的有符号整数。这是IntPtr on C#。LONG是一个扩展到long的宏。在Windows上,C++ long是一个32位有符号整数。因此,在C#方面,您需要使用int。CALLBACK意味着函数是stdcall。unsafe也根本不需要。你应该把它去掉。守则应是:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
public struct SENSDEVICEW
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)]
public string szSerialNo;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)]
public string szDeviceID;
public int nIndex;
}
[DllImport("...", CallingConvention=CallingConvention.Stdcall,
CharSet=CharSet.Unicode)]
static extern IntPtr SensFindDeviceW(int n, string pszMask,
ref SENSDEVICEW pDevice);最后,我假设pszMask是一个输入参数。因此,string是正确的。但是,当输入参数应该是C++时,LPWSTR代码将其声明为LPCWSTR。您可能希望检查此参数的语义。这当然感觉像一个输入参数,在这种情况下,C++编码器有点草率。
https://stackoverflow.com/questions/22246868
复制相似问题