如何从C++;到C#? 我使用DLIMPORT调用C++中的C++函数。
C#中的代码是: 函数如何从C++;到C#? 我使用DLIMPORT调用C++中的C++函数。,c++,.net,c#-4.0,C++,.net,C# 4.0,C#中的代码是: 函数ABC(inti)正常,但函数C(inti)在构建时产生以下错误: “指针和固定大小的缓冲区只能在不安全的上下文中使用” 我想我不明白如何导出函数的指针返回 有人能告诉我C#调用返回类型为指针的函数的正确方式吗?p/Invoke后来不知道如何将C样式数组从非托管端封送到托管端;与之不同的是,C样式数组中没有嵌入任何信息,P/Invoke稍后可以使用这些信息来确定应该复制多少字节 因此,您需要声明C函数以返回,然后调用将指针转换为托管端的字符串,如下所示: [DllImpor
ABC(inti)
正常,但函数C(inti)
在构建时产生以下错误:
“指针和固定大小的缓冲区只能在不安全的上下文中使用”
我想我不明白如何导出函数的指针返回
有人能告诉我C#调用返回类型为指针的函数的正确方式吗?p/Invoke后来不知道如何将C样式数组从非托管端封送到托管端;与之不同的是,C样式数组中没有嵌入任何信息,P/Invoke稍后可以使用这些信息来确定应该复制多少字节 因此,您需要声明
C
函数以返回,然后调用将指针转换为托管端的字符串,如下所示:
[DllImport("library.dll")]
public static extern IntPtr C(int i);
static int Main()
{
int k = ABC(10);
IntPtr b = C(1024);
string s = Marshal.PtrToStrAnsi(b);
// Problem: How do you release what is pointed to
// by IntPtr?
return 0;
}
此外,您必须将IntPtr
传递回非托管端,以释放分配给new
的内存;如果你不这样做,你会有内存泄漏
一个更简单的选择是为C++中的非托管库创建托管包装,它公开了调用函数并执行转换到<>代码>字符串<< /C> >(使用):
这些选项比完全在托管代码中处理要好,因为您不必担心在托管和非托管之间连续编组来处理指向非托管空间中分配的内存的指针。将返回类型声明为IntPtr,而使用Marshal.PtrToStringAnsi()将其转换为字符串。您无法修复可插拔内存泄漏,此API无法按原样使用。谢谢,它工作正常。但是C++有没有办法从C++函数中接收返回字符数组缓冲区,并将该数据缓冲区存储到C的字节[]中?我不想转换成字符串。谢谢@TTGroup更新了答案(参见上一个代码示例);前提是一样的,创建一个托管包装器,在那里进行数据操作,然后返回托管类型。我想实现一个队列数据结构,队列的每个元素都是一个指向char[]数组的指针,该数组包含二进制数据缓冲区。在C++方面:它将数据推送到队列中。在C端:它将从队列中弹出数据。我想在这里提到的主要目的是如何在不复制数据的情况下从队列中弹出数据。这意味着C#将通过获取指向该队列中数据的指针来弹出数据,而不是将字节一个字节复制为上述代码(对于(int index=0;index
using System.Runtime.InteropServices;
using System;
namespace DepartmentStore
{
class Exercise
{
[DllImport("library.dll")]
public static extern int ABC(int i);
[DllImport("library.dll")]
public static extern char* C(int i);
static int Main()
{
int k = ABC(10);
byte[] b = C(1024);
return 0;
}
}
}
[DllImport("library.dll")]
public static extern IntPtr C(int i);
static int Main()
{
int k = ABC(10);
IntPtr b = C(1024);
string s = Marshal.PtrToStrAnsi(b);
// Problem: How do you release what is pointed to
// by IntPtr?
return 0;
}
// compile with: /clr
#include <stdlib.h>
#include <string.h>
#include <memory>
#include <msclr\marshal.h>
using namespace System;
using namespace msclr::interop;
String^ WrappedC(int i) {
// Make the call to the native function.
// Let's store in an auto_ptr to handle
// cleanup when the wrapper is exited.
auto_ptr<char> c(C(i));
// Convert to a managed string and
// return.
return marshal_as<String^>(c.get());
}
// compile with: /clr
#include <stdlib.h>
#include <memory>
using namespace System;
using namespace msclr::interop;
String^ WrappedC(int i) {
// Make the call to the native function.
// Let's store in an auto_ptr to handle
// cleanup when the wrapper is exited.
auto_ptr<char> c(C(i));
// Copy the pointer.
char* p = c.get();
// The byte array to return.
// i is the size of the array, as per the call
// to C.
array<byte>^ a = gcnew array<byte>(i);
// Populate.
for (int index = 0; index < i; ++index)
a[index] = (byte) *p++;
// Return the array.
return a;
}