问题描述
我在 Linux 上使用 Mono/C#,并且有以下 C# 代码:
[DllImport("libaiousb")]extern static ResultCode QueryDeviceInfo(uint deviceIndex,ref uint PID、ref uint nameSize、StringBuilder 名称、ref uint DIOBytes,ref uint 计数器);
我调用了一个Linux共享库调用,定义如下:
unsigned long QueryDeviceInfo(无符号长设备索引, 无符号长 *pPID, 无符号长 *pNameSize, 字符 *pName, 无符号长 *pDIOBytes, 无符号长 *pCounters)
在调用 Linux 函数之前,我已将参数设置为已知值.我还在 Linux 函数的开头放了一个 printf,所有参数都按预期打印值.所以参数似乎从C#传递到Linux ok.返回值也不错.
但是,通过引用传递的所有其他参数都会返回垃圾.
我修改了 Linux 函数,因此它只是修改了值并返回.这是代码:
unsigned long QueryDeviceInfo(无符号长设备索引, 无符号长 *pPID, 无符号长 *pNameSize, 字符 *pName, 无符号长 *pDIOBytes, 无符号长 *pCounters) {printf ("PID = %d, DIOBYtes = %d, Counters = %d, Name= %s", *pPID, *pDIOBytes, *pCounters, pName);*pPID = 9;*pDIOBytes = 8;*pCounters = 7;*pNameSize = 6;返回 AIOUSB_SUCCESS;
所有的 ref 参数仍然作为垃圾返回.
有什么想法吗?
解决方案libaiousb.c
unsigned long QueryDeviceInfo(无符号长设备索引, 无符号长 *pPID, 无符号长 *pNameSize, 字符 *pName, 无符号长 *pDIOBytes, 无符号长 *pCounters){*pPID = 9;*pDIOBytes = 8;*pCounters = 7;*pNameSize = 6;返回0;}
libaiousb.so
<上一页>gcc -shared -o libaiousb.so libaiousb.cTest.cs
使用系统;使用 System.Runtime.InteropServices;使用 System.Text;类测试{[DllImport("libaiousb")]静态外部 uint QueryDeviceInfo(uint deviceIndex,ref uint pid,ref uint nameSize,StringBuilder 名称,ref uint dioBytes,ref uint 计数器);静态无效主要(){uint deviceIndex = 100;uint pid = 101;单位名称大小 = 102;StringBuilder 名称 = new StringBuilder("Hello World");uint dioBytes = 103;uint 计数器 = 104;uint 结果 = QueryDeviceInfo(deviceIndex,参考 pid,参考名称大小,名称,参考 dioBytes,参考计数器);Console.WriteLine(deviceIndex);Console.WriteLine(pid);Console.WriteLine(nameSize);Console.WriteLine(dioBytes);Console.WriteLine(计数器);Console.WriteLine(结果);}}
Test.exe
<上一页>gmcs 测试.cs运行:
<上一页>$ 单声道测试.exe10096870
I am using Mono/C# on Linux and have the following C# code:
[DllImport("libaiousb")]
extern static ResultCode QueryDeviceInfo(uint deviceIndex,
ref uint PID, ref uint nameSize, StringBuilder name,
ref uint DIOBytes, ref uint counters);
And I call a Linux shared library call defined as follows:
unsigned long QueryDeviceInfo(
unsigned long DeviceIndex
, unsigned long *pPID
, unsigned long *pNameSize
, char *pName
, unsigned long *pDIOBytes
, unsigned long *pCounters
)
I have set the parameters to known values before calling the Linux function. I've also put a printf at the beginning of the Linux function and all the parameters are printing values as expected. So the parameters seem to be passed from C# to Linux ok. The return value is also good.
However, all the other parameters that are passed by reference come back garbage.
I modified the Linux function so it simply modifies the values and returns. Here's that code:
unsigned long QueryDeviceInfo(
unsigned long DeviceIndex
, unsigned long *pPID
, unsigned long *pNameSize
, char *pName
, unsigned long *pDIOBytes
, unsigned long *pCounters
) {
printf ("PID = %d, DIOBYtes = %d, Counters = %d, Name= %s", *pPID, *pDIOBytes, *pCounters, pName);
*pPID = 9;
*pDIOBytes = 8;
*pCounters = 7;
*pNameSize = 6;
return AIOUSB_SUCCESS;
All the ref parameters still come back as garbage.
Any ideas?
libaiousb.c
unsigned long QueryDeviceInfo(
unsigned long deviceIndex
, unsigned long *pPID
, unsigned long *pNameSize
, char *pName
, unsigned long *pDIOBytes
, unsigned long *pCounters
)
{
*pPID = 9;
*pDIOBytes = 8;
*pCounters = 7;
*pNameSize = 6;
return 0;
}
libaiousb.so
gcc -shared -o libaiousb.so libaiousb.c
Test.cs
using System;
using System.Runtime.InteropServices;
using System.Text;
class Test
{
[DllImport("libaiousb")]
static extern uint QueryDeviceInfo(uint deviceIndex,
ref uint pid, ref uint nameSize, StringBuilder name,
ref uint dioBytes, ref uint counters);
static void Main()
{
uint deviceIndex = 100;
uint pid = 101;
uint nameSize = 102;
StringBuilder name = new StringBuilder("Hello World");
uint dioBytes = 103;
uint counters = 104;
uint result = QueryDeviceInfo(deviceIndex,
ref pid, ref nameSize, name,
ref dioBytes, ref counters);
Console.WriteLine(deviceIndex);
Console.WriteLine(pid);
Console.WriteLine(nameSize);
Console.WriteLine(dioBytes);
Console.WriteLine(counters);
Console.WriteLine(result);
}
}
Test.exe
gmcs Test.cs
Run:
$ mono Test.exe 100 9 6 8 7 0
这篇关于通过引用传递的参数使用 P/Invoke 返回垃圾的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!