陷入非常天真的问题。我有两个项目,一个是C ++,另一个是C#。想法是使用C ++项目作为一些C库的包装。并在C#中执行实际逻辑。
传递Value类型非常方便。但是参考类型我很难 没有使用 不安全或 DllImport 属性。
C ++
Cryptoki.Wrapper.h文件
using namespace System;
#pragma comment(lib, "legacy_stdio_definitions.lib")
namespace CryptokiWrapper {
public ref class CryptokiInit
{
public:
char* TESTString(char* test);
double TESTDouble(double test);
};
}
Cryptoki.Wrapper.cpp文件
#include "stdafx.h"
#include "Cryptoki.Wrapper.h"
using namespace std;
using namespace CryptokiWrapper;
char* CryptokiInit::TESTString(char* test)
{
char* r = test;
return r;
}
double CryptokiInit::TESTDouble(double test)
{
unsigned long int r = test;
return r;
}
C#代码
using System;
using System.Runtime.InteropServices;
using CryptokiWrapper;
namespace CallCryptoki
{
class Program
{
//[MarshalAs(UnmanagedType.LPTStr)]
//public String msg = "Hello World";
static void Main(string[] args)
{
CryptokiInit ob = new CryptokiInit();
//This Works
doubled d = ob.TESTDouble(99);
//But having hard time accepting the char* reference
//or sending string as refrence without using unsafe
// like
string text = "Hello World!";
string res = (*something*)ob.TESTString((*something*)text);
}
}
}
是否有任何类型的演员表(即 某事 )..... 无论如何,我能够轻松地执行此操作。 (只有参考传输就足够了,然后我可以构建字符串或对象)
就像另一个函数一样,使用double作为参数并返回类型。
虽然上面的例子只是说字符串,但是想要理解为概念,这样我就可以为两个项目之间的任何引用类型编写互操作(即C#和C ++)
提前感谢您的帮助!
答案 0 :(得分:0)
首先,这不是简单的C ++,而是C ++ / CLI - 主要是为托管/非托管代码互操作性而设计的。
您的C ++ / CLI函数可以使用.NET的字符串类型,如下所示:
int digit = 0, letter = 0, punc = 0;
char c;
String sentence = "abc, (kl{}";
for (int a = 0; a<sentence.length(); a++){
c=sentence.charAt(a);
if(Character.isLetter(c))
letter++;
if(Character.isDigit(c))
digit++;
if(("" + c).matches("[\\p{Punct}]")){
punc++;
}
}
System.out.println(punc);
}
System::String^ TESTString(System::String^ test);
表示托管参考,将其视为^
的托管等效文件。
现在,要在纯C ++中使用字符串数据,您有两种选择:
编组 - 见Overview of Marshaling in C++
例如,如果您需要将其转换为*
,请执行以下操作:
const char*
#include <msclr/marshal.h>
这将复制字符串数据,因为内存表示需要从2个字节的par字符更改为单个字符。
直接以msclr::interop::marshal_context ctx;
auto testCStr = ctx.marshal_as<const char*>(test);
// testCStr is freed when ctx goes out of scope
访问内存。您需要事先固定字符串,以免GC移动它。
const wchar_t*
#include <vcclr.h>
不以这种方式修改字符串数据。
要将字符串发送回管理方,您可以使用pin_ptr<const wchar_t> testCStr = PtrToStringChars(test);
// testCStr behaves just like a const wchar_t*
,也可以拨打marshal_as<System::String^>(yourCString)
;