结构说明
接口层次调用,最终实现C++调用C#接口的功能
-
实现层:C#接口,接口功能实现,生成.dll文件(C#)
-
中间层:C#与C++数据转换,调用C# dll,生成.lib文件
-
接口层:C++接口,调用.lib文件的接口,生成.dll文件(C++)
-
调用C++ dll接口
一、实现层 (C#)(.dll)
实现C#接口功能
namespace MyNamespace
{
class MyClass
{
public static bool Myfun(string text, ref string err_msg)
{
///实现具体功能...
return false;
}
};
};
二、中间层 (C++)(.lib)
将C#接口转换为C++接口
-
声明
bool lib_Myfun(LPCTSTR text, std::string& err_msg);
-
定义
...
...
#using <mscorlib.dll>
#using "..\MyTest.dll" //C# dll
using namespace MyNamespace; //C# dll 接口的命名空间
using namespace System;
using namespace Runtime::InteropServices;
using std::string;
static void MarshalString(String^ net, string& os)
{
const char* chars = (const char*)(Marshal::StringToHGlobalAnsi(net)).ToPointer();
os = chars;
Marshal::FreeHGlobal(IntPtr((void*)chars));
}
bool lib_Myfun(LPCTSTR text, std::string& err_msg)
{
String^% _msg = gcnew String("");
String^ _text = gcnew String(text);
bool result = MyClass::Myfun(_text, _msg);
MarshalString(_msg, err_msg);
return result;
}
三、接口层 (C++)(.dll)
将C++接口封装为C++类(还可以区分上命名空间)
-
声明
#pragma once
namespace MyNamespace2
{
class __declspec(dllexport) MyClass2
{
public:
static bool Myfun2(LPCTSTR text, std::string& err_msg);
}
};
-
定义
...
...
#include "libNeoway.h" //中间层的.lib的头文件
#pragma comment(lib,"myLib.lib") //依赖中间层的.lib
using namespace MyNamespace2;
using std::string;
bool MyClass2::Myfun2(LPCTSTR text, std::string& err_msg)
{
return lib_Myfun(imei, err_msg); //调用中间层的函数接口
}
四、调用 (C++)(.exe | .dll)
常规的C++ dll调用(静态调用或者动态调用)
总结
之所以多一个中间层,而不在调用层中直接调用C#的接口,是因为直接调用C#接口会用到 gcnew这类托管代码,这就需要将项目工程配置为 公共语言运行时支持(/clr),为了能使调用层的C++应用程序不用做这样的项目工程配置变动,所以使用中间层进行隔离。