C++ 与 c# 模块 之间相互调用
2015-08-22 12:31
585 查看
在项目中,遇到C++ 与 c#编写的模块之间的相互调用。
分两种情况:
1 c#模块使用C++模块的DLL(导出C API函数), 只需简单引用C++模块的 DLL即可。
2 c++模块调用c#模块DLL时,则需要使用一个适配模块(adapter), 它提供两个作用:1 导出C API供c++模块调用; 2 加戴加载C#模块DLL,并通过.NET基础时库的函数,获得C#类或函数名供调用。
示例说明:
C++ 工程 : SP (编译生成SP.dll)
some_dev.h:
class some_dev
{
public:
bool init_hook();
};
some_dev.cpp:
bool some_dev::init_hook()
{
return init_adapter("", "http://192.168.1.28/query_event.asmx"); // call C# function by C++
}
extern "C" __declspec(dllexport) on_recv(const char* data)
{
;
}
(managed C++ / clr 支持)工程: adapter (编译生成:adapter.dll )
adapter.h:
#ifdef WIN32
#ifdef ADAPTER_EXPORTS
#define ADAPTER_API __declspec(dllexport)
#else
#define ADAPTER_API __declspec(dllimport)
#endif
#else
#ifdef ADAPTER_EXPORTS
#define ADAPTER_API __attribute__((visibility("default")))
#else
#define ADAPTER_API
#endif
#endif
#include <string>
extern "C" ADAPTER_API bool init_adapter(const char* curr_path, const char* web_service_url);
adapter.cpp:
using namespace System;
using namespace System::Reflection;
namespace adapter {
public ref class wrapper
{
private:
static Assembly^ dll_ = nullptr;
static Assembly^ dll_ = nullptr;
static MethodInfo^ on_recv_cb_method_ = nullptr;
public:
static bool init(const char* dev_path, const char* web_service_url)
{
String^ path = gcnew String(dev_path);
path += "\\web_service_client_impl.dll";
try
{
wrapper::dll_ = Assembly::LoadFrom(path);
String^ url_string = gcnew String(web_service_url);
Type^ classType = wrapper::dll_->GetType("web_service_client_impl.api_wrapper");
MethodInfo^ method = classType->GetMethod("init");
method->Invoke((Type^)nullptr, gcnew array<Object^>(1){url_string });
}
catch (System::Exception^ e)
{
return false;
}
return true;
}
};
}
extern "C" ADAPTER_API bool init_adapter(const char* curr_path, const char* web_service_url)
{
return adapter::wrapper::init(curr_path, web_service_url);
}
C# 工程 : web_service (生成 web_service.dll)
namespace web_service_client_impl
{
internal static class SP_helper
{
[DllImport("SP.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void on_recv(byte[] data);
}
public class api_wrapper
{
static private string web_service_url_;
static public void init(string web_service_url)
{
api_wrapper.web_service_url_ = web_service_url;
}
public void on_recv(byte[] data)
{
SP_helper.on_recv(data); // call C API in SP.dll by C#
}
}
}
分两种情况:
1 c#模块使用C++模块的DLL(导出C API函数), 只需简单引用C++模块的 DLL即可。
2 c++模块调用c#模块DLL时,则需要使用一个适配模块(adapter), 它提供两个作用:1 导出C API供c++模块调用; 2 加戴加载C#模块DLL,并通过.NET基础时库的函数,获得C#类或函数名供调用。
示例说明:
C++ 工程 : SP (编译生成SP.dll)
some_dev.h:
class some_dev
{
public:
bool init_hook();
};
some_dev.cpp:
bool some_dev::init_hook()
{
return init_adapter("", "http://192.168.1.28/query_event.asmx"); // call C# function by C++
}
extern "C" __declspec(dllexport) on_recv(const char* data)
{
;
}
(managed C++ / clr 支持)工程: adapter (编译生成:adapter.dll )
adapter.h:
#ifdef WIN32
#ifdef ADAPTER_EXPORTS
#define ADAPTER_API __declspec(dllexport)
#else
#define ADAPTER_API __declspec(dllimport)
#endif
#else
#ifdef ADAPTER_EXPORTS
#define ADAPTER_API __attribute__((visibility("default")))
#else
#define ADAPTER_API
#endif
#endif
#include <string>
extern "C" ADAPTER_API bool init_adapter(const char* curr_path, const char* web_service_url);
adapter.cpp:
using namespace System;
using namespace System::Reflection;
namespace adapter {
public ref class wrapper
{
private:
static Assembly^ dll_ = nullptr;
static Assembly^ dll_ = nullptr;
static MethodInfo^ on_recv_cb_method_ = nullptr;
public:
static bool init(const char* dev_path, const char* web_service_url)
{
String^ path = gcnew String(dev_path);
path += "\\web_service_client_impl.dll";
try
{
wrapper::dll_ = Assembly::LoadFrom(path);
String^ url_string = gcnew String(web_service_url);
Type^ classType = wrapper::dll_->GetType("web_service_client_impl.api_wrapper");
MethodInfo^ method = classType->GetMethod("init");
method->Invoke((Type^)nullptr, gcnew array<Object^>(1){url_string });
}
catch (System::Exception^ e)
{
return false;
}
return true;
}
};
}
extern "C" ADAPTER_API bool init_adapter(const char* curr_path, const char* web_service_url)
{
return adapter::wrapper::init(curr_path, web_service_url);
}
C# 工程 : web_service (生成 web_service.dll)
namespace web_service_client_impl
{
internal static class SP_helper
{
[DllImport("SP.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void on_recv(byte[] data);
}
public class api_wrapper
{
static private string web_service_url_;
static public void init(string web_service_url)
{
api_wrapper.web_service_url_ = web_service_url;
}
public void on_recv(byte[] data)
{
SP_helper.on_recv(data); // call C API in SP.dll by C#
}
}
}
相关文章推荐
- 栈的应用2——超级计算器(中缀与后缀表达式)C语言
- 栈的应用1——超级计算器(中缀与后缀表达式)C语言
- C++ 编程个人总结
- C++中 explicit的用法
- GCC在C语言中内嵌汇编 asm __volatile__ (2)
- C语言编程技巧----如何定义全局变量----->提高代码可移植性
- C和C++中的文件读入写出区别
- C++联合
- Effective C++ 条款8 别让异常逃离析构函数
- 为何C语言(的函数调用)需要堆栈,而汇编语言却不需要堆栈
- C++模板的理解与使用
- C++模板的理解与使用
- 阶乘、斐波那契、 1的个数统计 c语言 实现备忘
- C++内存分配
- 用vs2013编写C语言与编写C++的区别
- C语言 malloc calloc realloc alloc 在分配内存时的 区别
- Majority Element
- C语言的二维和三维动态连续数组分配
- C语言中移位符需要注意的地方
- C++基本知识归纳(2)