一尘不染

通过引用传递的参数使用P / Invoke返回垃圾

linux

我在Linux上使用Mono / C#,并且具有以下C#代码:

[DllImport("libaiousb")]
extern static ResultCode QueryDeviceInfo(uint deviceIndex, 
    ref uint PID, ref uint nameSize, StringBuilder name, 
    ref uint DIOBytes, ref uint counters);

我调用一个Linux共享库调用,定义如下:

unsigned long QueryDeviceInfo(
      unsigned long DeviceIndex
    , unsigned long *pPID
    , unsigned long *pNameSize
    , char *pName
    , unsigned long *pDIOBytes
    , unsigned long *pCounters
    )

在调用Linux函数之前,我已经将参数设置为已知值。我还将printf放在Linux函数的开头,并且所有参数都按预期输出值。因此参数似乎是从C#传递到Linux的。返回值也不错。

但是,所有其他通过引用传递的参数都会返回垃圾。

我修改了Linux函数,以便仅修改值并返回。这是代码:

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;

所有ref参数仍然作为垃圾返回。

有任何想法吗?


阅读 276

收藏
2020-06-07

共1个答案

一尘不染

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);
    }
}

测试文件

gmcs Test.cs

跑:

$ mono Test.exe
100
9
6
8
7
0
2020-06-07