C++与C#互调dll的实现步骤
来源:互联网 发布:java 开源验证码 编辑:程序博客网 时间:2024/06/08 05:28
本文实例展示了C++与C#互调dll的实现步骤,在进行大型项目共享dll动态链接库中可以用到。具体方法如下:
一、C#调用C++ dll步骤(只能导出方法):
1. c++建立空项目->源文件文件夹中添加cpp文件和函数
2. c++属性设置中,配置类型设置为动态库dll,公共语言运行时支持改为/clr
3. c#引用c++的dll
4. c#声明c++的方法,并添加 DllImport特性
5. c#工程属性设置为:目标平台x86
6. 注意方法的类型匹配
7. 引发PInvokeStackImbalance异常:注意:C++的"_declspec"和C#的“CallingConvention=CallingConvention.Cdecl”
另外,可以通过VS的异常窗口,取消掉对 PInvokeStackImbalance异常的检测:
点击VS的“调试 - 异常”,打开异常窗口,展开选择“Managed Debugging Assistants\PInvokeStackImbalance”,去掉对应的“引发”可选框。
二、 c++调用 c# dll的步骤(可直接使用C#类):
1. 创建c++控制台应用程序
2. 拷贝c# dll到c++工程根目录
3. 工程属性->配置->常规->公共语言运行时支持->clr
工程属性->配置->c/c++常规->调试信息格式->zi
工程属性->配置->c/c++常规->公共语言运行时支持->clr
#using "CSharpDllProject.dll"
using
namespace
CSharpDllProject;
三、 c#调用c++类步骤(c++/cli,可直接使用C++类)
c++/cli简介:C++/CLI标准是基于Microsoft提交的标准C++与通用语言基础结构(Common Language Infrastructure)结合的技术
1.使用c++/cli语法对标准c++类进行包装(可采用聚合模式,引用标准c++类,实现所有标准c++的方法)
2.c#引用c++ dll后,可直接new出一个 c++/cli创建的托管类对象
下面就用一个完整的实例来详细说明怎样用托管C++封装一个C++类以提供给C#使用。
- //
NativeCppDll.h - #pragma
once - #ifndef
LX_DLL_CLASS_EXPORTS -
#define LX_DLL_CLASS __declspec(dllexport) - #else
-
#define LX_DLL_CLASS __declspec(dllimport) - #endif
- class
LX_DLL_CLASS CPerson - {
- public:
-
CPerson(); -
CPerson( wchar_t *pName, constwchar_t cSex, intiAge); -
SetName( constwchar_t *pName); -
* GetName(); -
SetSex( constwchar_t cSex); -
GetSex(); -
SetAge( intiAge); -
GetAge(); -
* GetLastError(); - private:
-
m_szName[128]; -
m_cSex; -
m_iAge; -
m_szLastError[128]; -
ShowError(); - };
- //
NativeCppDll.cpp - #include
"stdafx.h" - #include
"NativeCppDll.h" - #include
<iostream> - #include
<tchar.h> - using
namespace std; - CPerson::CPerson()
- {
-
wcscpy_s(m_szName, _T( Name" )); -
m_cSex = -
m_iAge = 0; -
wcscpy_s(m_szLastError, _T( Error" )); - }
- CPerson::CPerson(const
wchar_t *pName, constwchar_t cSex, intiAge) - {
-
wcscpy_s(m_szLastError, _T( Error" )); -
SetName(pName); -
SetSex(cSex); -
SetAge(iAge); - }
- void
CPerson::SetName( constwchar_t *pName) - {
-
((pName == NULL) || (wcslen(pName) == 0) || (wcslen(pName) > 127)) -
{ -
wcscpy_s(m_szName, _T( Name" )); -
wcscpy_s(m_szLastError, _T( length ));of the input name is out of range." -
ShowError(); -
-
} -
wcscpy_s(m_szName, pName); - }
- wchar_t
* CPerson::GetName() - {
-
m_szName; - }
- void
CPerson::SetSex( constwchar_t cSex) - {
-
((cSex 'F')!= && 'M')(cSex != && 'm')(cSex != && 'f'))(cSex != -
{ -
m_cSex = -
wcscpy_s(m_szLastError, _T( input ));sex is out of [F/M]." -
ShowError(); -
-
-
} -
m_cSex = cSex; - }
- wchar_t
CPerson::GetSex() - {
-
m_cSex; - }
- void
CPerson::SetAge( intiAge) - {
-
((iAge < 0) || (iAge > 150)) -
{ -
m_iAge = 0; -
wcscpy_s(m_szLastError, _T( input ));age is out of range." -
ShowError(); -
-
} -
m_iAge = iAge; - }
- int
CPerson::GetAge() - {
-
m_iAge; - }
- wchar_t
* CPerson::GetLastError() - {
-
m_szLastError; - }
- void
CPerson::ShowError() - {
-
cerr << m_szLastError << endl; - }
- //
ManageCppDll.h - #pragma
once - #define
LX_DLL_CLASS_EXPORTS - #include
"..\NativeCppDll\NativeCppDll.h" - using
namespace System; - namespace
ManageCppDll - {
-
ref classPerson -
{ -
包装所有类CPerson的公有成员函数 -
-
Person(); -
Person(String ^ strName, Char cSex, iAge); -
~Person(); -
property String ^ Name -
{ -
set(String ^ strName); -
String ^ get(); -
} -
property Char Sex -
{ -
set(Char cSex); -
Char get(); -
} -
property Age -
{ -
set( intiAge); -
get(); -
} -
String ^ GetLastError(); -
-
类CPerson的指针,用来调用类CPerson的成员函数 -
CPerson *m_pImp; -
}; - };
- //
ManageCppDll.cpp - #include
"stdafx.h" - #include
"ManageCppDll.h" - #include
<vcclr.h> - namespace
ManageCppDll - {
-
在构造函数中创建类CPerson的对象并在析构函数中将该对象销毁 -
所有的成员函数实现都是通过指针m_pImp调用类CPerson的相应成员函数实现 -
Person::Person() -
{ -
m_pImp = CPerson(); -
} -
Person::Person(String ^ strName, Char cSex, iAge) -
{ -
将string转换成C++能识别的指针 -
pin_ptr< wchar_t> wcName = PtrToStringChars(strName); -
m_pImp = CPerson(wcName, cSex, iAge); -
} -
Person::~Person() -
{ -
在析构函数中删除CPerson对象 -
m_pImp; -
} -
Person::Name::set(String ^ strName) -
{ -
pin_ptr< wchar_t> wcName = PtrToStringChars(strName); -
m_pImp->SetName(wcName); -
} -
String ^ Person::Name::get() -
{ -
gcnew String(m_pImp->GetName()); -
} -
Person::Sex::set(Char cSex) -
{ -
m_pImp->SetSex(cSex); -
} -
Char Person::Sex::get() -
{ -
m_pImp->GetSex(); -
} -
Person::Age::set( intiAge) -
{ -
m_pImp->SetAge(iAge); -
} -
Person::Age::get() -
{ -
m_pImp->GetAge(); -
} -
String ^ Person::GetLastError() -
{ -
gcnew String(m_pImp->GetLastError()); -
} - };
- using
ManageCppDll; - Person
person new= Person(); - person.Name
= "StarLee"; - person.Sex
= 'M'; - person.Age
= 28;
- C++与C#互调dll的实现步骤
- vc 下调用C#的dll步骤
- C#调用DLL的详细步骤
- java中调用c(c++)写的dll文件的实现及步骤
- java中调用c(c++)写的dll文件的实现及步骤
- java中调用c(c++)写的dll文件的实现及步骤
- java中调用c(c++)写的dll文件的实现及步骤(转)
- java中调用c(c++)写的dll文件的实现及步骤(转)
- java中调用c(c++)写的dll文件的实现及步骤
- java中调用c(c++)写的dll文件的实现及步骤
- java中调用c(c++)写的dll文件的实现及步骤
- C#调用C的DLL
- C#调用C++dll,C++中char*与C#类型的对应关系
- C#调用C++DLL的方法
- C#动态调用c++DLL的方法
- 编写C#调用的C++DLL
- 编写C#调用的C++DLL
- C#调用C++dll的类型转换
- JAVA获取月第一天、最后一天
- spring aop开发日志管理
- 怎样理解时间复杂度和空间复杂度
- 2017.2.16 日课
- +=
- C++与C#互调dll的实现步骤
- javascript中void()的用法
- 第一条博客
- Android_RecyclerView
- Intellij IDEA破解码
- Jsp中加载不了jpg的解决方案
- You Only Look Once论文中文翻译
- 位运算符总结
- Canvas 图形(Ru)扭曲(Yao)效果