繁体   English   中英

C dll的C ++ / CLI包装器

[英]C++/CLI wrapper for C dll

因此,我有了要在我的C#应用​​程序中使用的C.dll源代码。 我决定不使用DllImports,而是使用C ++ / CLI为它编写包装。

我的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#项目引用时,编译器将不接受对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代码函数的其他方式?

编辑:清理变量名称以提高可读性

如果您以其他方式执行此操作怎么办。 由于您具有处理C DLL和C#程序集之间的互操作职责的C ++ / CLI DLL,因此可以仅使用更多类似.NET的概念公开等效的API。

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

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

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

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

因此,对于托管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 );
}

};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM