我大部分的C/C++开发包括单片模块文件,绝对没有任何类,所以通常当我需要做一个DLL与使用的功能我只是使用标准的导出它们__declspec(dllexport)指令.然后通过LoadLibrary()头文件和lib文件动态地或在编译时访问它们.
如果要导出整个类(及其所有公共方法和属性),如何执行此操作?
是否可以在运行时动态加载该类,如果是,如何?
如何使用头和lib进行编译时链接?
我想在.NET中使用C++类,但我在使用Visual Studio(2008)构建时遇到了问题.
我有一个非托管类A(使用/ clr编译的C++).我创建了一个C++/clr类'Class1',它将A和匹配的方法委托包装到A的方法中.
如果我在Class1(托管)的类库项目中包含A类的单元源文件我没有问题所有链接和工作正常,但我有很多非管理的C++类,如A和我想把它们放在DLL中并链接到DLL到托管库(类包装器).[我实际上并不认为此时需要将这些DLL链接在一起,但编译器似乎需要它,给出下面显示的相同错误.]
我创建了VisualC++/CLR/Class库并添加了我的C++类(下面列出的A)并构建.[我使用了默认设置,但是在项目链接器设置中我已经尝试使用"是"和"否"注册输出.]没有错误,并且创建了.DLL文件.
我创建了VisualC++/CLR/Class库并创建了包装类'Class1'我使用了所有默认设置.在项目属性下,我单击了"引用""添加新引用"并选择了第一步中创建的DLL.
我收到链接器错误:
test_NET_library.obj : error LNK2028: unresolved token (0A000009) "public: int __thiscall Z::A::m1(int,int)" (?m1@A@Z@@$$FQAEHHH@Z) referenced in function "public: int __clrcall test_NET_library::Class1::m1(int,int)" (?m1@Class1@test_NET_library@@$$FQ$AAMHHH@Z)
test_NET_library.obj : error LNK2028: unresolved token (0A00000A) "public: int __thiscall Z::A::m2(int,int)" (?m2@A@Z@@$$FQAEHHH@Z) referenced in function "public: int __clrcall test_NET_library::Class1::m2(int,int)" (?m2@Class1@test_NET_library@@$$FQ$AAMHHH@Z)
test_NET_library.obj : error LNK2019: unresolved external symbol "public: int __thiscall Z::A::m1(int,int)" (?m1@A@Z@@$$FQAEHHH@Z) referenced in function "public: int __clrcall test_NET_library::Class1::m1(int,int)" (?m1@Class1@test_NET_library@@$$FQ$AAMHHH@Z)
test_NET_library.obj : error LNK2019: unresolved external symbol "public: …Run Code Online (Sandbox Code Playgroud) 我一直在谷歌搜索试图找到一个完全成熟的例子,但无济于事.
我有一个C++ API,它提供了许多包含纯虚方法的类,供开发人员使用.我试图做的是通过C++/CLI为C#提供这个接口.
我已经设法将API编译到C++/CLI库中,因为我是新手,所以我已经达到了一个难点.
我知道我需要创建一个包装器来将C++/CLI非托管类暴露给托管的.net类,但我没有找到一个可靠的示例或讨论,展示如何使用抽象的C++类来完成此操作.
任何人都可以指出我正确的方向,包括C#测试应用程序,它显示了如何为抽象类创建包装器的端到端.它似乎是"哦,你只是做X"的事情,但我不知道X是什么:).我在这里看到了几个例子,但它们并不是很清楚.自从我处理任何C#以来已经有3年了.
希望有人可以帮忙!
Sammich
我有一个用C++编写的DLL,它导出一个函数CreateRisk.该函数返回一个接口指针,如下所示:
extern "C"
{
__declspec(dllexport) IRisk* __stdcall CreateRisk()
{
return new Risk();
}
}
Run Code Online (Sandbox Code Playgroud)
IRisk派生自IUnknown并具有自定义方法Calculate:
class IRisk: public IUnknown
{
public:
virtual int __stdcall Calculate(int i,double s) = 0;
};
Run Code Online (Sandbox Code Playgroud)
Risk类实现了IRisk接口(这里省略了实现).
我想要的是在c#中调用CreateRisk函数并获取对IRisk的引用.
我在c#中定义了一个包装器接口
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IRisk
{
[PreserveSig]
int Calculate(int i,double s);
}
Run Code Online (Sandbox Code Playgroud)
我在C#中添加了一个dll条目
[DllImport("Risk.dll")]
extern static IntPtr CreateRisk();
Run Code Online (Sandbox Code Playgroud)
我可以在C#中调用CreateRisk并获取IntPtr的值类型.有没有办法将IntPtr编组到c#IRisk接口,以便我可以在C#中调用Calculate方法?
我曾尝试过Marshal.GetIUnknownForObjectInContext,Marshal.GetObjectForIUnknown,但无济于事.
我知道创建COM组件可以做到这一点.但是,COM组件需要在系统中注册.我想避免这些麻烦,让C#直接使用C++ dll导出的接口.
PS:
以下是我的Risk类实现:
class IRisk : public IUnknown
{
public:
virtual int __stdcall Calculate(int i,double y ) = 0;
};
class Risk:public IRisk
{
int count;
public: …Run Code Online (Sandbox Code Playgroud) 我正在进行C++项目.我想将它移植到C#.NET项目.我做了一些研究,我认为最流行的方法是使用pinvoke.
我不知道是否还有其他方法存在?
提前致谢.