C# C++/C dll的CLI包装器

C# C++/C dll的CLI包装器,c#,c++-cli,wrapper,dllimport,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#代码有它自己的结构定义和CBs的委托,因为我不能将.h附加到C#项目 因此,当我将C++/CLI dll显式

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

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

typedef struct
{
 PFN_IN readFp;
 PFN_OUT writeFp;
}OPEN_ARGS;
C++/CLI共享相同的.h文件,因此使用相同的typedef

C#代码有它自己的结构定义和CBs的委托,因为我不能将.h附加到C#项目

因此,当我将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代码函数


< >编辑:清除变量名以更好地准备< < /P> > P>请考虑使用SWIG为所有pPoECK.< /P>生成包装代码。

请考虑使用SWIG来生成所有pPoECK.< /P>的包装代码。


如果你用另一种方式来做呢。由于您有一个C++/CLI DLL来处理C DLL和C#汇编之间的互操作任务,因此您可以公开一个等效的API,只需使用更多类似.NET的概念

例如,您可以公开一个包含三个事件的类,而不是使用函数指针公开结构。C#程序集将为这些事件添加处理程序。在C++ DLL中,它将使用C DLL所期望的函数指针,但是它们的实现将触发C程序集处理的.NET事件。
这将提供更好的在C端使用DLL的体验,并可能消除您遇到的互操作编译器错误。

如果您以另一种方式这样做会怎么样。由于您有一个C++/CLI DLL来处理C DLL和C#汇编之间的互操作任务,因此您可以公开一个等效的API,只需使用更多类似.NET的概念

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

这将提供一个更好的使用DLL在C端的经验,并且可能消除你遇到的互操作编译器错误。

< P>这样,对于托管C++,你可以使用像你所使用的“PyPrimar托管/非托管编译器指令”而不是pJoNKE。然后,您可以将托管代码和本机代码一起编译到同一个程序集中,甚至是同一个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 );
}

};
#pragma管理
//在此处包含您的本地标题
#包括“foo.h”//不管你怎么称呼它。
#使用//您在这里还需要什么。。。
//必须在类中封装函数,因为.NET不允许独立函数。
公共参考类foo
{
公共静态int sarCLIOpen(int a,SARWrapperTest::Program::SAR\u OPEN\u ARGS ARGS)
{
//执行一些操作以将托管参数转换为本机参数。
::SAR\u OPEN\u ARGS native\u ARGS=。。。
//然后调用本机函数
返回sarCLIOpen(a,本地参数);
}
};

<>代码>对于托管C++,可以使用“γ”PrimaMabor /非托管编译器指令,而不是使用它所使用的pPoNoKE。然后,您可以将托管代码和本机代码一起编译到同一个程序集中,甚至是同一个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 );
}

};
#pragma管理
//在此处包含您的本地标题
#包括“foo.h”//不管你怎么称呼它。
#使用//您在这里还需要什么。。。
//必须在类中封装函数,因为.NET不允许独立函数。
公共参考类foo
{
公共静态int sarCLIOpen(int a,SARWrapperTest::Program::SAR\u OPEN\u ARGS ARGS)
{
//执行一些操作以将托管参数转换为本机参数。
::SAR\u OPEN\u ARGS native\u ARGS=。。。
//然后调用本机函数
返回sarCLIOpen(a,本地参数);
}
};

如果我的生命依赖于它,我不会考虑Sigg。如果我的生命依赖于它,我不会考虑Sigg。谢谢你的建议。听起来是个好主意。另外,由于某些原因,我无法对你的帖子投赞成票:oThanks赞成这个建议。听起来是个好主意。出于某种原因,我无法提升你的职位:如果我理解正确的话,这正是我正在做的。我的.c和.h源代码来自c++/CLI项目中包含的原始c dll。我正在将这个项目编译为另一个dll,我想在我的C#app中使用它。请注意,我的托管方法的函数签名。它需要一个受管理的SAR\u OPEN\u ARGS。。。这就是你在做的吗?您不能在托管参数列表中公开本机类型,这看起来像是根据上面的编译器错误进行的。是的,我认为这是一个有效的建议,尽管在包装中声明WrapperTest::Program::OPEN_参数而不是在调用它的C#app中声明WrapperTest::Program::OPEN_参数是有意义的,以避免紧密耦合。谢谢你的意见。如果我理解正确的话,这正是我正在做的。我的.c和.h源代码来自c++/CLI项目中包含的原始c dll。我正在将这个项目编译为另一个dll,我想在我的C#app中使用它。请注意,我的托管方法的函数签名。它需要一个受管理的SAR\u OPEN\u ARGS。。。这就是你在做的吗?您不能在托管参数列表中公开本机类型,这看起来像是根据上面的编译器错误进行的。是的,我认为这是一个有效的建议,尽管在包装中声明WrapperTest::Program::OPEN_参数而不是在调用它的C#app中声明WrapperTest::Program::OPEN_参数是有意义的,以避免紧密耦合。谢谢你的意见。