Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/161.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#-调用非托管C++;函数传递变量_C#_Pointers_Structure_Unmanaged_Variant - Fatal编程技术网

C#-调用非托管C++;函数传递变量

C#-调用非托管C++;函数传递变量,c#,pointers,structure,unmanaged,variant,C#,Pointers,Structure,Unmanaged,Variant,我想从托管代码调用以下函数: short LS_LoadConfig(LS_ID SensorID,LPVARIANT varConfigPathFile,BOOL bInit) 下面是我在C#类中声明extern函数的方式: 下面是如何创建VARIANT实例并获取指向它的指针。然后我调用C#函数: string filepath = @"C:\Windows\ ..."; IntPtr variantFilePath = Marshal.AllocCoTaskMem(200); Marsha

我想从托管代码调用以下函数:

short LS_LoadConfig(LS_ID SensorID,LPVARIANT varConfigPathFile,BOOL bInit)
下面是我在C#类中声明extern函数的方式:

下面是如何创建VARIANT实例并获取指向它的指针。然后我调用C#函数:

string filepath = @"C:\Windows\ ...";
IntPtr variantFilePath = Marshal.AllocCoTaskMem(200);
Marshal.GetNativeVariantForObject(filepath, variantFilePath);
LS_LoadConfig(device.Id, variantFilePath, initLineSensor);
问题是我一直收到错误消息,例如“调用LS_LoadConfig函数会使堆栈不平衡,请检查参数是否与非托管签名匹配”

问题似乎是由第二个参数“variantFilePath”引起的,比如它没有正确封送,并且它在非托管堆上的大小与地址的大小不一致(在我的例子中是32位)。我尝试将C#函数签名中的类型从IntPtr更改为int,如下所示:

[DllImport("LineSensor.dll", EntryPoint = "#16")]
    private static extern Int16 LS_LoadConfig(
        Int16 deviceId,
        int variantFilePath,
        int init);
我试图调用传递一个随机数的函数,结果稍微好了一点,我刚刚收到一个错误“内存访问冲突”。显然是因为随机数不是一个有效的地址

有人知道这个问题的解决办法吗


感谢您提供的有用信息。

您创建的访问冲突并没有更好。它还可以防止生成MDA警告。除了参数类型错误之外,int16看起来很奇怪,最有可能的问题是调用约定造成的。试试StdCall


并将第二个参数声明为“object”,其默认封送处理是到一个变量。使用“ref”关键字声明它以获得LPVARIANT。

您创建的访问冲突并不好。它还可以防止生成MDA警告。除了参数类型错误之外,int16看起来很奇怪,最有可能的问题是调用约定造成的。试试StdCall

并将第二个参数声明为“object”,其默认封送处理是到一个变量。使用“ref”关键字声明它以获得LPVARIANT

“调用LS_LoadConfig函数会导致堆栈失衡,请检查参数是否与非托管签名匹配”

这通常意味着您在本机代码和托管代码之间使用了冲突的调用约定。默认情况下,C#使用stdcall,C/C++使用cdecl。尝试指定CallingConvention=CallingConvention.Cdecl

“调用LS_LoadConfig函数会导致堆栈失衡,请检查参数是否与非托管签名匹配”


这通常意味着您在本机代码和托管代码之间使用了冲突的调用约定。默认情况下,C#使用stdcall,C/C++使用cdecl。请尝试指定CallingConvention=CallingConvention.Cdecl。

问题在于调用约定必须设置为Cdecl。因此[DllImport(“LineSensor.dll”,EntryPoint=“#16”,CallingConvention=CallingConvention.Cdecl)]修复了所有问题@Hans传递ref对象与传递LPVARIANT是一样的,但比我的解决方案更优雅。问题是调用约定必须设置为Cdecl。因此[DllImport(“LineSensor.dll”,EntryPoint=“#16”,CallingConvention=CallingConvention.Cdecl)]修复了所有问题@Hans传递ref对象与传递LPVARIANT是一样的,但比我的解决方案更优雅。
[DllImport("LineSensor.dll", EntryPoint = "#16")]
    private static extern Int16 LS_LoadConfig(
        Int16 deviceId,
        int variantFilePath,
        int init);