1.首先我们新建 一个C#的类库工程 CSharpLib
新建一个ExportClass类,增加一个GetID函数,如下:
1 public class ExplortClass 2 { 3 public int GetID() 4 { 5 return 1024; 6 } 7 }
2.新建一个CLR空工程CSBridge,这个库会作为中间桥接的库。将CSBridge工程的输出路径修改为CSharpLib工程的输出路径
说明:如果没有看到CLR Empty,可以到Visual Studio的安装程序中钩选并安装(直接搜索cli)
新建一个bridge.cpp。输入以下代码
1 #include <Windows.h> 2 #include<msclr/marshal_cppstd.h> 3 4 //引用C# dll 5 #using "https://blog.csdn.net/zhaotianff/article/details/CSharpLib.dll" 6 7 //引用命名空间 8 using namespace msclr::interop; 9 using namespace System; 10 using namespace System::Runtime::InteropServices; 11 using namespace CSharpLib; 12 13 #define lib_export 14 #ifdef lib_export 15 #define cs_lib_api extern "C" __declspec(dllexport) 16 #else 17 #define cs_lib_api __declspec(dllimport) 18 #endif 19 20 typedef int(__stdcall* funGetId)(); //定义函数指针 21 22 //导出函数 供C++调用 23 //在这个函数里调用 C#的函数,做为中转层 24 cs_lib_api int GetID() 25 { 26 CSharpLib::ExplortClass^ c = gcnew CSharpLib::ExplortClass(); 27 auto id = c->GetID(); 28 return id; 29 }
这样就拥有了一个桥接工程 。
3. 新建一个C++控制台应用程序,输入以下代码测试。
// CppInvoke.cpp : This file contains the 'main' function. Program execution begins and ends there. // #include <iostream> #include<Windows.h> typedef int(__stdcall* funGetId)(); int main() { HMODULE hInstance = LoadLibrary(L"CSBridge.dll"); if (hInstance) { funGetId getId = (funGetId)GetProcAddress(hInstance, "GetID"); if (getId) { auto result = getId(); std::cout << result << std::endl; } } }
可以看到输出结果为:1024
在CSharpLib中增加一个结构体Computer:
1 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 2 public struct Computer 3 { 4 public int cpuId; 5 public string cpuName; 6 public int osVersion; 7 }
增加一个获取Computer的函数
1 public Computer GetComputer() 2 { 3 Computer computer = new Computer(); 4 computer.cpuId = ; 5 computer.cpuName = "Intel"; 6 computer.osVersion = 11; 7 return computer; 8 }
然后在CSBridge中增加一个用于和Computer交互的类型interop_Computer,这个类型是用于C++中调用时使用,使用C#中的Computer类型转换可以得到interop_Computer。
1 struct interop_Computer 2 { 3 int cpuId; 4 wchar_t* cpuName; 5 int osVersion; 6 };
再定义一个函数指针和增加一个中转层函数
1 typedef interop_Computer(__stdcall* funGetComputer)(); 2 3 cs_lib_api interop_Computer GetComputer() 4 { 5 CSharpLib::ExplortClass^ c = gcnew CSharpLib::ExplortClass(); 6 auto computer = c->GetComputer(); //调用C#中的函数 7 System::IntPtr ptr = Marshal::AllocHGlobal(sizeof(interop_Computer));//需要提前分配空间 8 System::Runtime::InteropServices::Marshal::StructureToPtr(computer, ptr, false);//将C#中的结构体拷贝到Intptr 9 interop_Computer* rt = (interop_Computer*)(void*)(ptr.ToPointer());//将Intptr强制转换为interop_Computer 10 return *rt; 11 }
然后在CppInvoke中添加测试代码
HMODULE hInstance = LoadLibrary(L"CSBridge.dll"); if (hInstance) { funGetComputer getComputer = (funGetComputer)GetProcAddress(hInstance, "GetComputer"); if (getComputer) { auto computer = getComputer(); std::wcout << computer.cpuId << " " << computer.cpuName << " " << computer.osVersion << std::endl; } FreeLibrary(hInstance); }
输出结果为:
这种情况有两种方法可以实现:
1、将C++中的参数封送到C#中,转换方式和上面返回结构体的实现方式差不多。大概思路就是把C++结构体转换成IntPtr,再从IntPtr转换到C#中的结构体。
2、将C#中的函数转换到C++中的函数再调用。这样就可以直接使用C++中的结构体。
实现方法如下:
在C#中增加一个函数PrintComputer,需要传入一个Computer结构体。然后再增加对应的委托和获取委托的函数
1 public void PrintComputer(Computer computer) 2 { 3 Console.WriteLine(computer.cpuId); 4 Console.WriteLine(computer.cpuName); 5 Console.WriteLine(computer.osVersion); 6 }
1 public delegate void PrintComputerDelegate(Computer computer); //声明委托 2 4 public PrintComputerDelegate GetComputerDelegate() => PrintComputer; //定义返回委托的函数
在CSBridge中定义一个函数指针,并增加一个导出函数
1 typedef void(__stdcall* funPrintComputer)(interop_Computer computer); 2 3 cs_lib_api void PrintComputer(interop_Computer computer) 4 { 5 CSharpLib::ExplortClass^ c = gcnew CSharpLib::ExplortClass(); 6 auto printDelegate = c->GetComputerDelegate();//获取委托 7 IntPtr ptr = Marshal::GetFunctionPointerForDelegate(printDelegate);//将委托转为IntPtr类型 8 funPrintComputer funcPrint = (funPrintComputer)ptr.ToPointer();//将IntPtr转换为指针,再转换为funPrintComputer 9 if (funcPrint) 10 { 11 funcPrint(computer); 12 } 13 }
这样就可以在C++中的参数传递到C#中。CppInvoke中的调用 代码如下:
1 funPrintComputer printComputer = (funPrintComputer)GetProcAddress(hInstance, "PrintComputer"); 2 interop_Computer testComputer; 3 testComputer.cpuId = 18; 4 testComputer.cpuName = _tcsdup(L"AMD"); 5 testComputer.osVersion = 7; 6 if (printComputer) 7 { 8 printComputer(testComputer); 9 }
输出结果为:
示例代码(需要Visual Studio 2022)
方法二、将.NET组件导出为COM
待完成
到此这篇颜色代码怎么用(c++颜色代码怎么用)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/cjjbc/15228.html