我在一個有C鏈接的dll中觀察了一個函數。這個函數返回類的類型。我不確定這是如何實現的,因爲C不瞭解課堂。
我寫了一個示例DLL和程序自己,並指出VC++編譯器顯示此效果的警告,但不阻止你。程序能夠GetProcAddress這個函數並且調用它來接收返回的對象。課程定義已提供給程序。另外,如果我編寫一個C鏈接的函數,該函數返回一個類類型,甚至不會導出該類,編譯器不會發出任何警告。如果類定義可用,程序可以從dll中使用該函數。
有關如何工作的任何想法?這樣的行爲編譯器/平臺是特定的嗎?具有C連接能夠返回類類型的函數?
回答
您誤解了extern "C"
的行爲。
它只通過阻止name mangling影響目標文件中函數的名稱。它不會產生「更多C」或「更少C++」的函數。 extern "C"
向C++函數添加的唯一附加限制是不應重載。
一個類對象基本上只是一個struct對象,爲vtbl等提供了一些額外的「隱藏」成員。
但是,我不確定你的意思是「程序可以使用此函數,只要類定義可用」。 C會在看到class Blah { ... };
時發出編譯器錯誤。
對不起,我感到困惑。該程序是用C++編寫的,它使用的dll有一個C接口。我已經在上面解釋了Max Lybbert的回覆。 – 2011-01-24 14:27:28
有可能與C鏈接函數返回,不能用C,只要表示,因爲他們可以用C語言來操縱根據我的C++設計&演進的模仿對象(第11.3.3) :
我們考慮了幾種方案的類型安全聯動方案決定實際添加到語言[Stroustrup的,1988年]一前:...
- 僅提供類型安全聯動不可能是C函數的函數,因爲他們有不能用C表示的類型... ...
聲明爲具有C鏈接的函數仍具有C++調用語義。也就是說,必須聲明形式參數,並且實際參數必須在C++匹配和歧義控制規則下匹配。 ...如果我們爲C提供了特殊服務,我們將不得不爲C++編譯器[連接到Pascal,Fortran,PL/I等]添加一套無限制的語言調用約定。 ...
鏈接,語言間調用和語言間對象傳遞本質上是一個難題,並且有許多實現依賴的方面。 ......我希望我們沒有聽說過這件事的最後一件事。
也就是說,C++鏈接不基於所涉及的類型是否爲有效的C類型。這是一個有意的設計決定。它允許你創建用C編寫一個DLL ++但可以由C通過標題中所用:
// in the header
struct Foo; // forward declaration
#ifdef __cplusplus
extern "C" {
#endif
struct Foo* create_foo();
void destroy_foo(struct Foo*);
void foo_bar(struct Foo*);
#ifdef __cplusplus
} // extern "C"
// now declare Foo
struct Foo {
void bar();
};
#endif
// in the implementation file
#include <iostream>
extern "C" {
Foo* create_foo()
{
return new Foo();
}
void destroy_foo(Foo* f)
{
delete f;
}
void foo_bar(Foo* f)
{
f->bar();
}
}
void Foo::bar()
{
std::cout << "Foo::bar() called\n";
}
注到new
,delete
和std::cout
呼叫。這些都需要C++運行時。因此,實現文件必須用C++編譯,但由於函數具有C鏈接,因此可以使用C或C++頭文件。
那麼如何在C中獲得Foo
?在這種情況下,你不這樣做,因爲沒有辦法在頭文件中以C會理解的方式完全聲明它。相反,C只能看到前向聲明,這會創建一個不完整的類型。 C不知道不完整類型有多大,所以C函數不能直接創建它或直接對它們進行操作,但C知道指向不完整類型的指針有多大,因此C可以在指向不完整類型的指針類型。你可以得到更多的創造性和實際創建C++ POD類型,你可以直接在C.
Foo*
s運行在 ,你沒有真正定義在C Foo
結構。碰巧APR uses a similar design(「創建APR類型」,我找不到更好的鏈接)。
- 1. 函數不能返回具有相同的接口類型爲返回類型
- 2. C++類函數的返回類型定義,返回一個類
- 3. 具有不同返回類型的C++多態函數
- 4. C#類函數返回類(性能)
- 5. 不返回值,從函數具有非void返回類型
- 6. Objective-C:具有塊返回類型的塊的類型簽名
- 7. C++函數指針的返回類型
- 8. C#函數的返回類型
- 9. c語言。函數的返回類型
- 10. C++函數的返回類型
- 11. 具有多種返回類型的類?
- 12. C++成員函數鏈接返回類型和派生類
- 13. C#接口返回類型
- 14. C# - 函數的返回類型與參數的返回類型相同
- 15. 推導其參數的返回類型函數返回類型
- 16. 函數功能返回任何類型
- 17. C++查找函數返回類型
- 18. C宏/函數返回多種類型
- 19. C++按返回類型選擇函數
- 20. 函數返回類型在C++中
- 21. 具有通用返回類型的可選函數參數
- 22. 功能具有不同的返回類型和parameteres C++
- 23. 靜態構造函數不能有返回類型,但靜態方法必須在C#中有返回類型
- 24. jdbc連接sqlite連接類的返回類型
- 25. Java:一種具有多種返回類型的函數......泛型可能嗎?
- 26. C++:如何定義一個具有泛型返回類型的虛函數?
- 27. Infere函數返回類型
- 28. PgAdmin函數返回類型
- 29. 函數返回類型decission
- 30. typedefing函數返回類型
有一些技巧,那就是如何在C++中實現控制的反轉。你有一些鏈接或例子嗎? – 2011-01-20 08:02:04
類簽名會很有用。否則,我們只是猜測。 – 2011-01-20 08:28:01
你知道類型不存在於二進制級別嗎? – 2016-05-10 15:23:04