2012-06-21 54 views
2

在DLL中,我做鑄造空指針跨越DLL

std::vector<foo*>* v = new std::vector<foo*>(); 
foo* f = new foo(); 
v->push_back(f); 
// size of v is 1 
process->Result = static_cast<void*>(v); // Result is of type void* 

和使用DLL的一個exe,我做

if (process->Result != NULL) 
{ 
    std::vector<foo*>* v = static_cast<std::vector<foo*>*>(process->Result); 
    int size = v->size(); // <-- size is garbage (221232 or something like that) 

} 

結果必須是一個void*。有誰知道我爲什麼不能正確地傳回載體?我在做什麼錯了嗎?

由於

+1

的地址是雙方的一樣嗎?你是否用完全相同的運行時庫*和*編譯選項來編譯兩邊? –

+0

@GregHewgill地址在雙方都是一樣的,但是dll是使用vs2005創建的,而exe是使用vs2010創建的。 –

+0

對,那絕對不行。由於標準庫數據結構(如std :: vector)是在頭文件中實現的,因此編譯器版本之間的實際數據表示形式可能會有所不同。 –

回答

4

因爲諸如std::vector在頭文件中實現的標準庫的數據結構,實際的數據表示可以是編譯器的版本之間不同。如果您使用VS2005和其他代碼使用VS2010編譯了一些代碼,則無法以這種方式可靠地返回std::vector

假設foo是組件之間完全相同的數據佈局,您可以返回已分配HeapAlloc的指針的原始數組foo*。請勿使用malloc(),因爲您的組件正在使用不同的運行時庫,並且您不能使用分配給其他分配器的東西。通過使用HeapAllocHeapFree,您正在使用在整個過程中共享的Win32標準分配器。

舉例來說,你可以這樣做:

v->push_back(f); 
HANDLE heap = GetProcessHeap(); 
foo **r = (foo **)HeapAlloc(heap, 0, (v->size() + 1) * sizeof(foo *)); 
std::copy(v.begin(), v.end(), r); 
r[v->size()] = NULL; // add a sentinel so you know where the end of the array is 
process->Result = r; 

,然後你調用模塊:

foo **v = static_cast<foo**>(process->Result); 
for (int i = 0; v[i] != NULL; i++) { 
    printf("index %d value %p\n", i, v[i]); 
} 
HANDLE heap = GetProcessHeap(); 
HeapFree(heap, 0, v); 
+0

我從來沒有使用過'HeapAlloc()'。你能夠以問題中的例子顯示它的用法,或者指向解釋用法的資源。 –

+0

關於std :: vector在頭文件中的好答案,請參閱我的問題:http://stackoverflow.com/questions/5661738/common-practice-in-dealing-with-warning-c4251-class-needs-to -have-dll-inter,其中有一個來自John Dibling的出色答案。 –

+0

在您的HeapAlloc示例上:爲什麼簡單的數組Foo * []不起作用,並與int numFoos結合?當然,所有這一切都假設Foo類本身可以安全地跨越dll邊界傳輸...... –