Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# DLLImport型问题_C#_C++_Pinvoke - Fatal编程技术网

C# DLLImport型问题

C# DLLImport型问题,c#,c++,pinvoke,C#,C++,Pinvoke,我正试图将一个C DLL导入到我的C#项目中。 .h代码如下所示: _declspec(dllexport) LRESULT CALLBACK SensFindDeviceW(LONG n, LPWSTR pwszMask, PSENSDEVICEW pDevice); _senseDeviceW结构: typedef struct _SENSDEVICEW { WCHAR szSerialNo[32]; WCHAR szDeviceID[32]

我正试图将一个C DLL导入到我的C#项目中。 .h代码如下所示:

 _declspec(dllexport)   LRESULT CALLBACK SensFindDeviceW(LONG n, LPWSTR pwszMask, PSENSDEVICEW pDevice);
_senseDeviceW结构:

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(不起作用)并按如下方式编组字符数组:

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
string szSerialNo;
但这会导致堆栈不平衡


也许你们中的任何人都知道我还可以尝试什么来让dll工作?

我发现以下问题:

  • LRESULT
    是指针大小的有符号整数。这就是C#上的
    IntPtr
  • LONG
    是扩展到
    LONG
    的宏。在Windows上,C++ <代码>长< /COD>是一个32位有符号整数。因此,在C端,您需要使用
    int
  • 结构声明错误(请参见下文)。您无法通过引用传递结构
  • 回调
    表示函数为
    stdcall
  • 也完全不需要
    不安全
    。你应该把它去掉
  • 代码应为:

    [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
    是正确的。但是,当输入参数应该是代码> LPCWSTR 时,C++代码声明它是“代码> LPWSTR < /代码>。您可能希望检查此参数的语义。当然,这是一个输入参数,在这种情况下C++程序员有点邋遢。

    谢谢你,很好用。是的,pszMask是一个输入参数。