C dll的C ++ / CLI包装器

时间:2011-06-17 15:54:11

标签: c# c++-cli wrapper dllimport

所以我有这个C .dll源代码,我想在我的C#应用​​程序中使用它。我决定用C ++ / CLI编写一个包装器,而不是做一堆DllImports。

My C函数接受一个指向结构的指针,其中包含4个回调函数:

typedef struct
{
 PFN_IN readFp;
 PFN_OUT writeFp;
}OPEN_ARGS;

C ++ / CLI共享相同的.h文件,因此使用相同的typedef。

C#代码有自己对此结构的定义和CB的委托,因为我无法将.h附加到C#项目。

    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate Int32 PFN_OUT(IntPtr arg, IntPtr pSrc, Int32 len);

    [StructLayout(LayoutKind.Sequential)]
    public struct OPEN_ARGS
    {
        public PFN_IN readFp;
        public PFN_OUT writeFp;
    };

因此,当我将C ++ / CLI dll显式添加到C#项目引用时,compliler将不接受对C ++ / CLI函数的调用

"Error 2 Argument 2: cannot convert from 'WrapperTest.Program.OPEN_ARGS' to 'SAR_OPEN_ARGS'"

但是,如果我隐含地像这样包含C ++ / CLI dll

[DllImport("Wrapper.dll", CharSet = CharSet.Auto, EntryPoint = "?CLIOpen@@YAHHUOPEN_ARGS@@@Z")]
public static extern int CLIOpen(int a, OPEN_ARGS args);

它会正常工作。

那么有没有办法告诉C#编译器忽略这种类型转换错误,或者可能是其他方式来包装C代码函数?

编辑:清理变量名称以获得更好的可读性

3 个答案:

答案 0 :(得分:4)

如果你这样做会怎么样?由于您有一个C ++ / CLI DLL来处理C DLL和C#程序集之间的互操作职责,因此您可以公开一个等效的API,只使用更多类似.NET的概念。

例如,您可以公开一个包含三个事件的类,而不是使用函数指针公开struct。 C#程序集将为这些事件添加处理程序。在C ++ DLL中,它将使用C DLL期望的函数指针,但它们的实现将触发C#程序集正在处理的.NET事件。

这将在C#端使用DLL提供更好的体验,并且可能摆脱您遇到的互操作编译器错误。

答案 1 :(得分:0)

请考虑使用SWIG为您的所有pinvoke生成包装代码。

http://www.swig.org/Doc1.3/CSharp.html

答案 2 :(得分:0)

因此,对于托管C ++,您可以使用#pragma托管/非托管编译器指令而不是pInvoke,它看起来就像您正在使用的那样。然后,您可以将托管代码和本机代码一起编译到同一个程序集中,甚至是相同的CPP文件。

然后你可以这样做:

#pragma managed
// include your native headers here
#include "foo.h" // whatever you call it.

#using <System.dll> // what ever else you need here...

// Have to wrap a function in a class, since .NET doesn't allow free standing functions.
public ref class foo
{
public static int sarCLIOpen(int a, SARWrapperTest::Program::SAR_OPEN_ARGS args)
{
// do something to convert your managed args to native args. 
::SAR_OPEN_ARGS native_args = ...
// then call your native function
return sarCLIOpen(a, native_args );
}

};
相关问题