[英]How to pass a string argument from C++ to a managed C# DLL
我正在编写一个需要调用用 C# 编写的 DLL 的 C++ 程序。 我按照这些说明创建了我的 C# DLL 并从我的 C++ 链接到它。
https://support.microsoft.com/en-us/kb/828736
我有一个将字符串作为参数的 C# 函数。 如何将 C++ 中的字符串传递到 C# 中?
我找不到这个问题的简明答案,所以我把我的解决方案放在这里,希望它可以帮助将来的某个人。
TL;DR:您需要使用 BSTR 在 C# 和 C++ 之间来回传递字符串。
这是我如何做到的。
这是我的 C# 代码示例。 需要注意的几点:
interface
部分中声明。stringToPrint
参数的方式。 以[MarshalAs(UnmanagedType.BStr)]
开头的string
至关重要。string
参数。 您不需要像在 C++ 中那样从C# 中的BSTR
进行转换。 更多关于下面的内容。//Reference where I got all this:
//https://support.microsoft.com/en-us/kb/828736
// Class1.cs
// A simple managed DLL that contains a method to add two numbers.
using System;
using System.Runtime.InteropServices;
namespace ManagedDLL
{
// Interface declaration.
public interface ICalculator
{
//Test functions
int Add(int Number1, int Number2);
int ReturnAge();
string StringTest();
void PrintAString([MarshalAs(UnmanagedType.BStr)] string stringToPrint);
};
// Interface implementation.
public class ManagedClass : ICalculator
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//Test functions
public int Add(int Number1, int Number2)
{
return Number1 + Number2;
}
public int ReturnAge()
{
return 35;
}
public string StringTest()
{
return "Can you hear me now?";
}
public void PrintAString([MarshalAs(UnmanagedType.BStr)] string stringToPrint)
{
Console.WriteLine("Trying to print a BSTR in C#");
Console.WriteLine(stringToPrint);
Console.WriteLine("Done printing");
}
}
}
在 C++ 中需要注意的一些事情:
#import
调用。 这是您告诉 C++ 如何找到您的 C# 库的地方。 我在问题中链接到的教程中提到了这一点。AddTest()
函数。BSTR
类型变量传递给 C#。 将std::string
转换为BSTR
相当容易,我有在任一方向进行转换的函数。//csLink.h
#include <windows.h>
#include <iostream>
#include <string>
#import "path/to/C#/dll.tlb" raw_interfaces_only
using namespace std;
namespace Sample{
class CSLink {
public:
CSLink();
//Test functions
int AddTest(int i1, int i2);
int AgeTest();
string StringTestCall();
void stringArgTest(string s);
private:
ICalculatorPtr pCalc;
long lResult;
string convertBSTR(BSTR *s);
BSTR convertBSTR(string s);
};
}
//csLink.cpp
#include "stdafx.h"
#include "csLink.h"
using namespace std;
namespace Sample{
//Constructor
CSLink::CSLink(){
cout << "You have created a CS Link" << endl;
//https://support.microsoft.com/en-us/kb/828736
HRESULT hr = CoInitialize(NULL);
pCalc = ICalculatorPtr(__uuidof(ManagedClass));
lResult = 0;
}
//Test functions
int CSLink::AddTest(int i1, int i2){
cout << "you are adding " << i1 << " and " << i2 << endl;
pCalc->Add(i1, i2, &lResult);
cout << "The result should have been " << i1 + i2 << " and it was " << lResult << endl;
return 0;
}
int CSLink::AgeTest(){
cout << "Trying to get my age" << endl;
pCalc->ReturnAge(&lResult);
return lResult;
}
string CSLink::StringTestCall(){
BSTR s;
pCalc->StringTest(&s);
return convertBSTR(&s);
}
void CSLink::stringArgTest(string s)
{
//References I used figuring this all out:
//http://stackoverflow.com/questions/28061637/how-to-pass-string-parameters-between-c-and-c
//https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshalasattribute(v=vs.110).aspx
//http://forums.codeguru.com/showthread.php?193852-How-to-convert-string-to-wstring
//http://stackoverflow.com/questions/6284524/bstr-to-stdstring-stdwstring-and-vice-versa
BSTR bSTR = convertBSTR(s);
cout << "~~~~~~~~~~~~~~~~~~~~~~~" << endl;
cout << "Testing conversion: " << convertBSTR(&bSTR) << "|end test" << endl;
pCalc->PrintAString(bSTR);
cout << "~~~~~~~~~~~~~~~~~~~~~~~" << endl;
}
//Utility functions
string CSLink::convertBSTR(BSTR *s){
if (*s == nullptr){
return "NULL STRING";
}
else{
wstring ws(*s, SysStringLen(*s));
string ss(ws.begin(), ws.end());
return ss;
}
}
BSTR CSLink::convertBSTR(string s){
wstring wStr = wstring(s.length(), L' ');
copy(s.begin(), s.end(), wStr.begin());
return SysAllocStringLen(wStr.data(), wStr.size());
}
}
就是这样。 有任何问题可以评论,我会尽力回答。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.