2010-05-15 69 views
0

有一個靜態類Pipe,在我包含的C++頭文件中定義。Objective-C/C++ - 鏈接器錯誤/方法簽名問題

靜態方法我很感興趣調用(從Objective-C的)是在這裏:

static ERC SendUserGet(const UserId &_idUser,const GUID &_idStyle,const ZoneId &_idZone,const char *_pszMsg); 

我訪問出現存儲用戶ID的副本的Objective-C的數據結構,和了zoneid - 它看起來像:

@interface DataBlock : NSObject 
{ 
    GUID userID; 
    GUID zoneID; 
} 

查找了GUID def,它是一個結構與一堆重載操作符相等。 UserId和ZoneId從第一個函數簽名是#typedef GUID

現在,當我嘗試調用該方法,無論我如何投它(const UserId),(UserId)等,我得到以下鏈接器錯誤:

Ld build/Debug/Seeker.app/Contents/MacOS/Seeker normal i386 
cd /Users/josh/Development/project/Mac/Seeker 
setenv MACOSX_DEPLOYMENT_TARGET 10.5 
/Developer/usr/bin/g++-4.2 -arch i386 -isysroot /Developer/SDKs/MacOSX10.5.sdk -L/Users/josh/Development/TS/Mac/Seeker/build/Debug -L/Users/josh/Development/TS/Mac/Seeker/../../../debug -L/Developer/Platforms/iPhoneOS.platform/Developer/usr/lib/gcc/i686-apple-darwin10/4.2.1 -F/Users/josh/Development/TS/Mac/Seeker/build/Debug -filelist /Users/josh/Development/TS/Mac/Seeker/build/Seeker.build/Debug/Seeker.build/Objects-normal/i386/Seeker.LinkFileList -mmacosx-version-min=10.5 -framework Cocoa -framework WebKit -lSAPI -lSPL -o /Users/josh/Development/TS/Mac/Seeker/build/Debug/Seeker.app/Contents/MacOS/Seeker 

Undefined symbols: 
    "SocPipe::SendUserGet(_GUID const&, _GUID const&, _GUID const&, char const*)", referenced from: 
    -[PeoplePaneController clickGet:] in PeoplePaneController.o 
ld: symbol(s) not found 
collect2: ld returned 1 exit status 

這是一個類型/函數簽名錯誤,或真正的某種鏈接錯誤?我有所有這些類型和靜態類定義的標題#imported - 我也試過#include,以防萬一,因爲我已經絆倒了:P

原諒我,我來自一個Web技術背景,所以這種C風格的內存管理和不可變性的東西超級朦朧。

編輯:添加完整的鏈接器錯誤文本。將「功能」更改爲「方法」。另外我會注意到我們使用一個自定義的makefile來編譯這個項目的一些外部項目。儘管在這個xcode項目中引用了SocPipe靜態方法,但似乎編譯得很好。

+1

這並不是完整的鏈接器錯誤 - 請在粘貼之前抓住一兩行。 – 2010-05-15 22:44:28

+0

此外,'SendUserGet'肯定不是一個函數,它是一個靜態方法。如果它是一個函數,它將不會生成鏈接器錯誤,因爲它被聲明爲「靜態」。是的,'static'意味着完全取決於它是出現在類定義的內部還是外部。 – 2010-05-15 22:50:49

+0

方法然後。編輯。 – Josh 2010-05-15 23:00:24

回答

1

(嗯,讓我們把這一評論到答案。)

方法簽名看起來不錯;也就是說,您所調用的內容與頭中聲明的內容相匹配。如果不是,你可能會得到一個編譯錯誤而不是鏈接錯誤。

鏈接器的問題是,它沒有任何相應的目標代碼這個呼叫接續到:該方法是聲明但從未定義

後者應出現在您的項目可以編譯的C++源文件中,或者在您可以鏈接到的某個預編譯庫或框架中。無論哪種方式,該文件需要包含在您的項目中,以便它可以提供給鏈接器。

+0

啊。你指出我到底什麼是錯的。在實現中(理論上已包含在項目中),有一個ifdef可以排除這個特定的塊被編譯。哎呀!也許在API中有另一種方法可以滿足我的需求,我猜。非常感謝。 – Josh 2010-05-15 23:43:16

+0

啊,好的。似乎對整個方法實現#ifdef-ed out非常反常,因爲它會中斷接口。 – walkytalky 2010-05-15 23:50:51

1

包含Pipe::SendUserGet的目標文件沒有被構建,或者它沒有被鏈接到Xcode目標中。如果這些方法在頭文件中定義,Pipe中的其他靜態方法是否正確工作並不一定相關。

您提到您使用外部makefile來構建項目的某些部分。在這種情況下,在編譯時將makefile作爲依賴運行是不夠的 - 您還必須將結果產品包含在項目中。

例如,如果您有一個構建libLIBRARY.a的生成文件,然後將libLIBRARY.a拖入您的項目並將其添加到您的目標。

這隻適用於makefile構建庫的情況。如果makefile生成一個程序,它將不起作用。如果庫是一個動態庫,它也會變得更加複雜,因爲您還必須確保動態庫與您的應用程序一起分發(通常通過將其放入應用程序包中,如果您正在製作應用程序包) 。如果你想建立一個通用的二進制文件,它也會變得更加複雜。理論上你可以將正確的CFLAGS傳遞給make來構建一個通用庫,但是對於每個體系結構運行一次make並使用腳本(這是我所做的)組合結果可能會更容易。

+0

感謝您的額外細節。我認爲這裏發生的事情是,在移植過程中(從win32到mac),這個特定的實現被作爲TODO得到了解決,然後他們把頭文件中的方法def留給頭撞我。好哇!我不知道c/C++/objective-c的錯誤,足以知道該怎麼回事。 – Josh 2010-05-15 23:51:52