2013-05-06 66 views
6

我有一個無符號整數數組,需要存儲指向數據和函數的指針以及一些數據。在我使用的設備中,sizeof指針與sizeof unsigned int相同。我如何將指針轉換爲無符號整型函數?我知道這使得代碼不可移植,但它是微控制器特定的。我嘗試這樣做:投射函數C++中的整數指針

stackPtr[4] = reinterpret_cast<unsigned int>(task_ptr); 

,但它給我一個錯誤「無效的類型轉換」

澆鑄成空指針,然後以int是凌亂。

stackPtr[4] = reinterpret_cast<unsigned int>(static_cast<void *> (task_ptr)); 

有沒有乾淨的做法呢?

編輯 - task_ptr是函數指針void task_ptr(void)

愛Barmar的回答,把我的可移植性的缺點了。同樣,void指針的數組實際上更有意義,然後是Unsigned Ints。謝謝Barmar和isaach1000。編輯2:明白了,我的編譯器正在考慮大內存模型,所以它使用的是32位指針,而不是我期待的16位指針(帶有17K總內存的小型微型指針)。

+1

你不能讓數組成爲void指針數組嗎? – isaach1000 2013-05-06 15:07:51

+4

如何使用函數指針和數據指針的聯合? – Barmar 2013-05-06 15:09:45

+1

只要(a)整數類型足夠大並且(b)它是一個指向普通(非成員或靜態成員)函數的指針,一個簡單的'reinterpret_cast'應該工作。這是這種情況嗎?什麼是'task_ptr'? – 2013-05-06 15:20:34

回答

4

C型鑄件可以將八邊形釘固定到梯形孔中,所以我會說,鑑於您非常特定的目標硬件和要求,我會使用該鑄件,可能會將其包裹到模板中以便更清晰。

或者,雙擊到void*,然後int的確具有讓代碼脫穎而出的優點,使您的未來維護者知道正在發生的事情並且可以特別關注。

編輯評論: 看來你的編譯器可能有一個bug。下面的代碼編譯的G ++ 4.5:

#include <iostream> 

int f() 
{ 
    return 0; 
} 

int main() 
{ 
    int value = (int)&f; 

    std::cout << value << std::endl; 
} 

EDIT2: 您也不妨考慮使用intptr_t類型,而不是int。這是一個足以容納指針的整數類型。

+0

當我使用C風格轉換時,C++編譯器返回一個錯誤: '錯誤[Pe171]:無效類型轉換' – user1135541 2013-05-06 16:25:56

+1

+1對'intptr_t' – Oktalist 2013-05-06 18:39:23

+1

不幸的是,'intptr_t'沒有被指定爲允許轉換函數指針事情是這樣的對對象的指針,有沒有類似的函數指針,無論是:-(。所以,有以確保您的代碼將無法被編譯的系統中的函數指針將不適合在'intptr_t'沒有明顯的方式。 – SamB 2015-09-23 18:03:49

-1

這是符合ANSI標準:

int MyFunc(void* p) 
{ 
    return 1; 
} 

int main() 
{ 
    int arr[2]; 
    int (*foo)(int*); 

    arr[0] = (int)(MyFunc); 

    foo = (int (*)(int*))(arr[0]); 

    arr[1] = (*foo)(NULL); 
} 
+0

試過了,但我的C++抱怨,'無效類型conversion'。需要做的標準C++方式。 – user1135541 2013-05-06 16:30:04

+0

這在C編譯以及++了。你會得到什麼確切的錯誤? – lsalamon 2013-05-06 16:47:15

+3

我最後一次檢查,'無效的主要()'是非標準。 – 2013-05-06 17:03:04

2

在C++中的指針可以被轉換爲一體型大到足以容納它的值。有條件支持的類型std::intptr_t定義爲您可以將void*轉換爲intptr_t並返回以獲取原始值。如果void*的大小等於或大於平臺上的函數指針,則可以按照以下方式進行轉換。

#include <cstdint> 
#include <cassert> 

void foo() {} 

int main() { 
    void (*a)() = &foo; 

    std::intptr_t b = reinterpret_cast<std::intptr_t>(a); 

    void (*c)() = reinterpret_cast<void(*)()>(b); 
    assert(a==c); 
} 
+0

即使存在'intptr_t',是否有條件地支持'a'是否可以重新解析爲'b'。 (但是,如果存在這種支持,則保證'a == c')。 – 2017-12-13 03:47:37