我正在嘗試將 C 庫包裝到 C /CLI 庫中以在 C# 中使用。我在型別之間轉換時遇到問題...
C 函式看起來像這樣(這是來自 MyCppLib.h 檔案,我無法更改 C 代碼):
int CppFunc(void* Handle, wchar_t* Feature, long long* Value)
我的 C /CLI 包裝器函式如下所示:
#include "MyCppLib.h"
#include <msclr\marshal.h>
#include <string.h>
#include <stdlib.h>
using namespace System;
using namespace System::Runtime::InteropServices;
using namespace msclr::interop;
namespace MyCppCliLib
{
int CppCliFunc(IntPtr Handle, String^ Feature, long long* Value) {
return ::CppFunc(Handle.ToPointer(), string_to_wchar(Feature), Value);
}
static wchar_t* string_to_wchar(String^ managedString)
{
marshal_context^ context = gcnew marshal_context();
wchar_t* unmanagedString = context -> marshal_as<wchar_t*>(managedString);
delete context;
return unmanagedString;
}
}
但是,似乎我無法將 String^ 編組為 wchar_t* ... 錯誤 C2065 說“不支持此轉換”。雖然如果我用 替換它const wchar_t*,它似乎作業......我不明白......而且我不確定我是否正確轉換了 Handle 和 Value 型別......
如何將 C void*、wchar_t* 和 long long* 型別轉換為 C /CLI?
uj5u.com熱心網友回復:
該marshal_context班是土生土長的型別,而不是一個垃圾收集型別。所以你不能寫gcnew marshal_context()
預期用途如下:
marshal_context context;
const wchar_t* unmanagedString = context.marshal_as<const wchar_t*>(managedString);
// use unmanagedString
// when context goes out of scope, both the context object and the memory for unmanagedString are freed
但是你有一個問題,你想回傳一個指標。您的問題或代碼中沒有任何內容涉及string_to_wchar與其呼叫者之間關于最終應如何釋放記憶體的合同。我們可以通過注意到您的輔助函式太短而無法使用來避免這個問題,因此您可以消除它:
#include <msclr\marshal.h>
int CppCliFunc(IntPtr Handle, String^ Feature, long long* Value)
{
marshal_context context;
return ::CppFunc(Handle.ToPointer(),
context.marshal_as<const wchar*>(Feature),
Value);
}
現在字串資料在::CppFunc需要它的時候仍然存在。
但是,您需要一個非const指標。 System::String^意味著是不可變的(實際上不是,這會導致一些問題),因此該marshal_as庫會阻止您獲得可寫指標。但是,您可以輕松獲得指向字串副本的可寫指標:
#include <msclr\marshal_cppstd.h>
int CppCliFunc(IntPtr Handle, String^ Feature, long long* Value)
{
std::wstring strFeature{marshal_as<std::wstring>(Feature)};
return ::CppFunc(Handle.ToPointer(),
&stdFeature[0],
Value);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/325438.html
上一篇:在C 中洗掉動態陣列會導致錯誤
