2008-11-20 12 views
7

मैं किसी भी मामले में kernel32.lib की तुलना में सीआरटी, या किसी अन्य आयात के बिना कंसोल एप्लिकेशन बनाने की कोशिश कर रहा हूं। मैं संकलित करने के लिए मेरे कोड मिलता है, लेकिन कुछ समस्याओं के आसपास लिंकर रैप नहीं कर सकते हैं:सीआरटी और डिफ़ॉल्ट शीर्षलेख के बिना कंसोल ऐप्स बनाना?

unresolved external symbol @[email protected] 
unresolved external symbol "int __cdecl FreeLibrary(void *)" ([email protected]@[email protected]) 
unresolved external symbol "void * __cdecl LoadLibraryW(wchar_t *)" ([email protected]@[email protected]) 
unresolved external symbol "int (__cdecl*__cdecl GetProcAddress(void *,char *))(void)" ([email protected]@[email protected]) 
unresolved external symbol _wmainCRTStartup 

FreeLibrary, LoadLibraryW और GetProcAddress मैं में लेकर आए हैं, स्पष्ट रूप से कार्यक्रम, windows.h का उपयोग नहीं:

#pragma comment(lib, "kernel32.lib") 

typedef int(*FARPROC)(); 

void* LoadLibraryW(wchar_t* lpLibFileName); 
FARPROC GetProcAddress(void* hModule, char* lpProcName); 
int FreeLibrary(void* hLibModule); 

मुझे लगता है कि मेरे प्रोटोटाइप में कुछ गड़बड़ है। हालांकि, बड़ी समस्या __security_check_cookie और _wmainCRTStartup है, जो स्पष्ट रूप से सीआरटी के साथ कुछ करने के लिए है। तो मैं सोच रहा हूं कि मैं एंट्रीपॉइंट के लिए डिफ़ॉल्ट int wmain(int argc, wchar_t* argv[]) ओवरराइड करने के बारे में और सुरक्षा कुकी के किसी भी चीज़ से छुटकारा पाने के तरीके के बारे में सोचूंगा।

उत्तर

4

_wmainCRTStartup समारोह है कि wmain कॉल()

यह IIRC कुछ ओ फ़ाइल है कि आप अपने lib निर्देशिका में देखने के साथ लिंक कर सकते हैं, में उपलब्ध होना चाहिए है। Reduce EXE and DLL Size with LIBCTINY.LIB (और मैट पिएट्रेक चट्टानों :-)

1

आप अपने kernel32 आयात के लिए आवश्यक प्रोटोटाइप देखने के लिए Windows.h में देख सकते हैं। सामान्य रूप से, विंडोज फ़ंक्शन को WINAPI परिभाषित किया जाता है जो वास्तव में __stdcall है और __cdecl नहीं है। इससे कम से कम उस समस्या को ठीक कर दिया जाएगा।

अपने अन्य समस्या के रूप में, आप लिंकर कमांडलाइन तर्कों का पता लगाने और अगर वहाँ एक तरीका यह सीआरटी से चीजों के लिए नहीं देखने के लिए प्राप्त करने के लिए है देखने के लिए की जरूरत है। मुझे नहीं पता कि ऐसा करने का कोई तरीका है या नहीं। लेकिन आपको एक रास्ता खोजना होगा या उन कार्यों को स्वयं को परिभाषित करना होगा (जो आप शायद नहीं करना चाहते हैं)।

मैं बस एक अलग कंपाइलर/लिंकर का उपयोग करने की सिफारिश करता हूं।

+0

असल में मैंने उन्हें पहले से ही स्टडकॉल के रूप में आजमाया, और इसने समस्या को हल नहीं किया। – anon6439

0

उचित प्रविष्टि बिंदु main() है, wmain() नहीं (क्योंकि आप एक कंसोल ऐप संकलित कर रहे हैं)। सुरक्षा कुकी कोड को सीआरटी स्रोत कोड से हटाया जा सकता है; में लिंक करने की कोई जरूरत।

+0

wmain यूनिकोड के लिए कंसोल एंट्री पॉइंट है। – anon6439

1

आप के रूप में निर्वासन 'सी' windows.h कार्यों की घोषणा करने की जरूरत है:

हो सकता है कि यह उपयोगी पढ़ने भी है।

+0

धन्यवाद! यह हल हो गया। – anon6439

3

ठीक है, अगर किसी और को यह जानकारी मिलती है तो यह पता लगाने के लिए खुद को उत्तर देने का उत्तर दें।

जैसा कि एमएसल्टर्स ने सलाह दी थी, सुरक्षा कुकी कोड को सीआरटी स्रोत से चोरी किया जा सकता है, लेकिन ऐसा करने से मुझे पता चला कि /GS- कंपाइलर ध्वज सुरक्षा सामग्री से पूरी तरह से बचने के लिए उपयोग किया जा सकता है।

के रूप में सोपबॉक्स कहा, एपीआई काम करता है, __stdcall होने की जरूरत है और साथ ही प्रवेश बिंदु है। मैंने लिंकर कमांड लाइन ध्वज /entry:wmain के साथ एंट्री पॉइंट इश्यू तय किया।

और अंत में, के रूप में टोमेक ने कहा, एपीआई कार्यों होगा extern सी में हो!

तो:

#pragma comment(lib, "kernel32.lib") 

typedef int(*FARPROC)(); 

extern "C" { 
    void* __stdcall LoadLibraryW(wchar_t* lpLibFileName); 
    FARPROC __stdcall GetProcAddress(void* hModule, char* lpProcName); 
    int __stdcall FreeLibrary(void* hLibModule); 
    typedef int (__stdcall *f_MessageBoxW_t)(unsigned long hWnd, wchar_t* lpText, wchar_t* lpCaption, unsigned long uType); 
    f_MessageBoxW_t fnMsg; 
    void* hUser; 
}; 

int __stdcall wmain(int argc, wchar_t* argv[]) 
{ 
    hUser = LoadLibraryW(L"user32.dll"); 
    fnMsg = (f_MessageBoxW_t)GetProcAddress(hUser, "MessageBoxW"); 
    fnMsg(0, L"foo", L"bar", 0); 
    FreeLibrary(hUser); 
    return 0; 
} 
+1

मैं सिर्फ एक उत्तर लिख रहा था जिसमें '/ एंट्री' विकल्प शामिल था जब मैंने देखा कि आपके स्वयं के उत्तर में सबकुछ बहुत कुछ है: 1. 'windows.h' सहित आपके निष्पादन योग्य एक बिट के आकार को चोट नहीं पहुंचाएगी। यदि आप वास्तव में सुनिश्चित होना चाहते हैं तो '# WIN32_LEAN_AND_MEAN परिभाषित करें' और '# WIN32_EXTRA_LEAN परिभाषित करें। Win32 शीर्षलेखों में सीआरटी हेडर शामिल नहीं हैं, इसलिए यहां कोई समस्या नहीं होगी। 2. आप शायद पहले से ही ऐसा कर रहे हैं, लेकिन लिंकर को '/ NODEFAULTLIB' पास करें और मैन्युअल रूप से kernel32.lib आदि से लिंक करें। यह वास्तव में परिणामी निष्पादन योग्य आकार बहुत नीचे मिलता है। – rubenvb

2

अधिक सही प्रवेश बिंदु घोषणा हो जाएगा:

int __stdcall wmain(PVOID ThreadParam) 

सीआरटी प्रविष्टि BaseThreadInitThunk द्वारा सीधे बुलाया बिंदु के बिना। यह कुछ करने के लिए सूचक पास करता है, लेकिन argc + argv नहीं।

संबंधित मुद्दे