当前位置:  开发笔记 > 编程语言 > 正文

托管C++以形成c#和C++之间的桥梁

如何解决《托管C++以形成c#和C++之间的桥梁》经验,为你挑选了2个好方法。

我有点生疏,实际上我的C++真的很生疏.从大学一年级开始就没有触及它,所以已经有一段时间了.

无论如何,我正在做与大多数人相反的事情.从C++调用C#代码.我在网上做了一些研究,似乎我需要创建一些托管C++来形成一个桥梁.使用__declspec(dllexport)然后从中创建一个dll并使用整个东西作为包装器.

但我的问题是 - 我真的很难找到例子.我找到了一些基本的东西,有人想将C#版本用于String.ToUpper(),但这是非常基本的,只是一个小代码片段.

任何人都有任何想法,我可以在哪里寻找更具体的东西?注意,我不想使用COM.目标是根本不触及C#代码.



1> CuppM..:

虽然lain打我写一个例子,但无论如何我都会发布它以防万一......

编写包装器以访问自己的库的过程与访问其中一个标准.Net库的过程相同.

示例C#类代码在名为CsharpProject的项目中:

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在本例中)并使用a #ifdef在头文件中的C/C++接口中设置导出宏来完成.非托管接口头文件必须包含非托管内容(或者由预处理器过滤掉).

非托管C++接口头文件(CppInterface.h):

#pragma once

#include 

// 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 

// .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 

// 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());
}



2> Iain..:

在visual studio中创建一个新的C++/CLI项目,并添加对C#dll的引用.假设我们在DotNetLib.dll这个类中调用了一个C#dll :

namespace DotNetLib
{
    public class Calc
    {
        public int Add(int a, int b)
        {
            return a + b;
        }
    }
}

现在将CLR C++类添加到C++/CLI项目中:

// TestCPlusPlus.h

#pragma once

using namespace System;
using namespace DotNetLib;

namespace TestCPlusPlus {

    public ref class ManagedCPlusPlus
    {
    public:
        int Add(int a, int b)
        {
            Calc^ c = gcnew Calc();
            int result = c->Add(a, b);
            return result;
        }
    };
}

这将从C++调用C#.

现在,如果需要,您可以将本机C++类添加到C++/CLI项目中,该项目可以与CLR C++类进行通信:

// Native.h
#pragma once

class Native
{
public:
    Native(void);
    int Add(int a, int b);
    ~Native(void);
};

和:

// Native.cpp
#include "StdAfx.h"
#include "Native.h"
#include "TestCPlusPlus.h"

Native::Native(void)
{
}

Native::~Native(void)
{
}

int Native::Add(int a, int b)
{
    TestCPlusPlus::ManagedCPlusPlus^ c = gcnew TestCPlusPlus::ManagedCPlusPlus();
    return c->Add(a, b);
}

您应该能够正常地从任何其他本机C++ DLL调用Native类.

另请注意,Managed C++与C++/CLI不同并且已被C++/CLI取代.维基百科解释得最好:

http://en.wikipedia.org/wiki/C%2B%2B/CLI

推荐阅读
殉情放开那只小兔子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有