none
C#调用C动态链接库中任意参数个数的函数问题 RRS feed

  • 问题

  • 在c#工程中,通过dll调用c写好的底层软件,其中一个函数的形式如下:

    int fun( byte a1, byte* a2, int* a3, byte* a4, ...)

    任意参数“...”部分的参数有多种数据类型,包括byte,byte*,UInt16,UInt32等

    之前尝试过:

    1.  [DllImport("xxx.dll")]

            private static extern int fun(
                                                    byte a1,
                                                    [MarshalAs(UnmanagedType.LPArray)]byte[] a2,
                                                    UInt16* a3,
                                                    [MarshalAs(UnmanagedType.LPArray)]byte[] a4,
                                                    __arglist);

    2.  [DllImport("xxx.dll")]

            private static extern int fun(
                                                    byte a1,
                                                    [MarshalAs(UnmanagedType.LPArray)]byte[] a2,
                                                    UInt16* a3,
                                                    [MarshalAs(UnmanagedType.LPArray)]byte[] a4,
                                                    params object[] value);

    但是在调用时都出现问题,提示无法在DLL中找到入口点。请问大家这种情况该如何处理?


    • 已编辑 Ran1026 2013年1月28日 4:20
    2013年1月28日 4:19

答案

  • 可以用 IntPtr 来实现。

    C++中你提到的方法的实现应该为这样,同时我还得假设可变参数的个数是通过 a1 来描述的,然后可变参数类型应该为 byte:

    int fun( BYTE a1, BYTE* a2, int* a3, BYTE* a4, ...)

    {

      va_list args;
      va_start(args,a4);

      for(int i =0;i<a1;i++)

    {

    BYTE id = va_arg(args,BYTE);  // 读取 1 BYTE ,并移动到下一个位置。

    }

       va_end(args);

    }

    所以在C#中,你知道了你要传的参数个数后,你需要先分配一个非托管内存,比如:

    IntPtr ptr = Marshal.Malloc(8 * 10);

    然后填写你的值:

    Marshal.WriteByte(ptr,3);

    最后调用 fun.

    2013年1月29日 1:52