2008-08-25 164 views
1

我有一箇舊的C庫,需要一個無效**功能:指針指向託管C++

oldFunction(void** pStuff); 

我試圖從託管C調用此函數++(m_pStuff是父成員引用類類型爲void *的):

oldFunction(static_cast<sqlite3**>( &m_pStuff)); 

這讓我從Visual Studio以下錯誤:

錯誤C2440:'的static_cast:不能CONVER從'cli :: interior_ptr'到'void **'

我在猜測編譯器正在將void *成員指針轉換爲背後的cli :: interior_ptr。

有關如何做到這一點的任何建議?

回答

1

編輯:修復答案,見下文。

真的,你需要知道什麼oldFunction將與pStuff做什麼。如果pStuff是指向一些非託管的數據,你可以嘗試包裝m_pStuff的定義有:

#pragma unmanaged 

void* m_pStuff 

#pragma managed 

這將使得非託管的指針,然後可以傳遞到非託管函數。當然,你不能直接爲這個指針指定任何託管對象。

基本上非託管和託管指針是不相同的,不能轉換沒有某種膠水代碼複製底層數據。基本上託管指針指向託管堆,因爲這是垃圾收集,他們指向的實際內存地址可以隨時間變化。沒有明確這樣做,非託管指針不會更改內存地址。

從頭開始,你不能在類定義中定義非託管/託管。但這種測試代碼似乎就好了工作:

// TestSol.cpp : main project file. 

#include "stdafx.h" 

using namespace System; 

#pragma unmanaged 

void oldFunction(void** pStuff) 
{ 
    return; 
} 

#pragma managed 

ref class Test 
{ 
public: 
    void* m_test; 

}; 

int main(array<System::String ^> ^args) 
{ 
    Console::WriteLine(L"Hello World"); 

    Test^ test = gcnew Test(); 
    void* pStuff = test->m_test; 
    oldFunction(&pStuff); 
    test->m_test = pStuff; 

    return 0; 
} 

在這裏,我複製指針出了管理對象的第一,然後通過在通過向oldFunction。然後我將結果(可能由oldFunction更新)複製回管理對象。由於託管對象位於託管堆上,因此編譯器不會讓您傳遞對象中包含的指針的引用,因爲它可能在垃圾收集器運行時移動。

0

感謝您的建議,指針指向C風格的抽象結構,我認爲如果我將該結構暴露給託管代碼,由於缺少定義的結構會導致進一步的痛苦。所以我想我會做的是用C++封裝C庫,然後用託管C++封裝C++封裝,這將防止將這些C結構暴露給託管代碼。