C++ 与 c# 模块 之间相互调用

在项目中,遇到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#
        }

    }

}






猜你喜欢

转载自blog.csdn.net/zhaozhencn/article/details/47858313