从C#到C ++的编组

时间:2009-07-31 14:02:47

标签: c# c++ marshalling

我必须将C#应用程序中的InParameter传递给VC ++ DLL中的导出函数。该函数接受2个参数:

int func_name (FILE* fp, BYTE& by);

fp为In,by为Out参数。

我在考虑使用IntPtrFILE*编组并使用BYTE字节。这是对的吗?如果我在C#中写下以下内容

[DllImport("name_of_project.dll", CharSet = CharSet.Ansi)] public static extern int      func_name(IntPtr FilePointer, [MarshalAs(UnmanagedType.BYTE&)] byte by);
它会起作用吗?我认为它会给'&'带来错误签署编组声明。如何通过引用传递out参数?

非常感谢您的帮助。

谢谢,Viren

2 个答案:

答案 0 :(得分:2)

不,这不会像写的那样有用。

  1. 你将在C#程序中获得FILE*的位置?除非你的非托管dll中的某些其他函数给你这个指针,否则你会遇到麻烦。顺便说一下,我强烈建议将FILE*包裹在SafeHandle;那么你的p / invoke签名将使用SafeFilePointer而不是裸IntPtr
  2. 你编组了多少字节?如果只有一个,请将out byte by放入托管签名(不需要属性)。
  3. 您不需要指定字符集,因为您没有整理任何charstring

答案 1 :(得分:1)

如果本机函数需要引用,您可以使用它ref / out封送它。所以在你的情况下,你可以使用: out byte by。我已经检查过了,它对我有用。

再次编辑:我刚刚想到,我给你的建议不起作用,因为FILE是一个结构,你将无法轻易地从c#编组。因此,如果您将SafeFileHandle威胁为非托管库中的HANDLE对象,则可以使用此方法。如果你不能修改这个dll,一个解决方案是使用stdio创建自己的包装器来创建文件,它可能如下所示:

  1. 创建暴露fopen,fclose等功能的库。 (在c ++中):
    FILE* CreateFile(char* name);
  2. Marhall这个函数,在这个例子中你会使用(c#):
    public static extern IntPtr CreateMyFile([MarshalAs( UnmanagedType.LPStr)] string name);
  3. 将所有FILE *参数传递给IntPtr,然后将函数CreateMyFile的结果作为FILE *传递。