无论如何,我正在做大多数人做的事情.从C调用C#代码.我在网上做了一些研究,似乎我需要创建一些管理C来形成桥梁.使用__declspec(dllexport),然后创建一个dll,并将整个东西作为一个包装器.
但我的问题是 – 我真的很难找到例子.我发现一些基本的东西,有人想使用C#版本的String.toupper(),但这是非常基本的,只是一个小代码片段.
任何人都有什么想法可以在哪里寻找更具体的东西?注意,我不想使用COM.目标是不要碰C#代码.
解决方法
编写包装器以访问自己的库的过程与访问一个标准的.Net库一样.
using System; namespace CsharpProject { public class CsharpClass { public string Name { get; set; } public int Value { get; set; } public string GetdisplayString() { return string.Format("{0}: {1}",this.Name,this.Value); } } }
您将创建一个受管理的C类库项目(例如CsharpWrapper),并添加您的C#项目作为参考.为了使用相同的头文件进行内部使用和引用项目,您需要一种使用正确的declspec的方法.这可以通过定义预处理器指令(在这种情况下为CSHARPWRAPPER_EXPORTS)并使用#ifdef在头文件中的C/C++接口中设置导出宏来完成.非管理的接口头文件必须包含非托管的东西(或者由预处理器滤除).
非管理C接口头文件(CppInterface.h):
#pragma once #include <string> // Sets the interface function's decoration as export or import #ifdef CSHARPWRAPPER_EXPORTS #define EXPORT_SPEC __declspec( dllexport ) #else #define EXPORT_SPEC __declspec( dllimport ) #endif // Unmanaged interface functions must use all unmanaged types EXPORT_SPEC std::string GetdisplayString(const char * pName,int iValue);
然后,您可以创建一个内部头文件,以便能够包含在托管库文件中.这将添加using namespace语句,并且可以包括您需要的帮助器函数.
管理C接口头文件(CsharpInterface.h):
#pragma once #include <string> // .Net System Namespaces using namespace System; using namespace System::Runtime::InteropServices; // C# Projects using namespace CsharpProject; ////////////////////////////////////////////////// // String Conversion Functions inline String ^ ToManagedString(const char * pString) { return Marshal::PtrToStringAnsi(IntPtr((char *) pString)); } inline const std::string ToStdString(String ^ strString) { IntPtr ptrString = IntPtr::Zero; std::string strStdString; try { ptrString = Marshal::StringToHGlobalAnsi(strString); strStdString = (char *) ptrString.ToPointer(); } finally { if (ptrString != IntPtr::Zero) { Marshal::FreeHGlobal(ptrString); } } return strStdString; }
然后你只需编写你的接口代码来做包装.
托管C接口源文件(CppInterface.cpp):
#include "CppInterface.h" #include "CsharpInterface.h" std::string GetdisplayString(const char * pName,int iValue) { CsharpClass ^ oCsharpObject = gcnew CsharpClass(); oCsharpObject->Name = ToManagedString(pName); oCsharpObject->Value = iValue; return ToStdString(oCsharpObject->GetdisplayString()); }
然后在非托管项目中包含非托管头,告诉链接器在链接时使用生成的.lib文件,并确保.Net和包装DLL与您的非托管应用程序在同一个文件夹中.
#include <stdlib.h> // Include the wrapper header #include "CppInterface.h" void main() { // Call the unmanaged wrapper function std::string strdisplayString = GetdisplayString("Test",123); // Do something with it printf("%s\n",strdisplayString.c_str()); }
原文地址:https://www.jb51.cc/c/115563.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。