Trang 1 trên tổng số 3 123 Cuối cùngCuối cùng
Từ 1 tới 10 trên tổng số 28 kết quả

Đề tài: name mangling trong C và C++ tác dụng thế nào?

  1. #1
    Ngày gia nhập
    11 2008
    Bài viết
    78

    Mặc định name mangling trong C và C++ tác dụng thế nào?

    Em đang gặp rắc rối với name mangling trong quá trình nạp DLL. Mong các bác hướng dẫn

    Chương trình sử dụng nạp DLL:
    Code:
    #include <windows.h>
    #include <stdio.h>
    
    typedef void (*pf)();
    
    int main()
    {
    	pf Hello;
    	HMODULE hLib = LoadLibrary("DLL.dll");
    
    	if (hLib == NULL) {
    		printf("Can't load dll\n");
    		return -1;
    	}
    
    	Hello = (pf)GetProcAddress(hLib, "Hello");
    
    	if (Hello == NULL) {
    		printf("Can't load function\n");
    		return -1;
    	}
    
    	Hello();
    	FreeLibrary(hLib);
    	return 0;
    }
    DLL:
    Code:
    #include <stdio.h>
    
    __declspec(dllexport) void Hello()
    {
    	printf("Hello\n");
    }
    Nếu nạp DLL kiểu load-time sử dụng import libary thì sử dụng bình thường.
    Nhưng nếu nạp kiểu run-time mà không có extern "C" thì vẫn nạp dll bình thường nhưng không cách nào nạp được hàm void Hello().
    Em đã xem qua tài liệu về name mangling thì có nói rằng extern "C" chỉ cần thiết khi viết DLL bằng ngôn ngữ C++ mà muốn export ra C-Interface để các ngôn ngữ khác có thể sử dụng được. Còn nếu chỉ dùng C++ thì không cần thiết. Thế nhưng trong trường hợp này nếu bỏ extern "C" thì em không thể sử dụng hàm trong DLL được . Các bác giải thích cho em với

  2. #2
    Ngày gia nhập
    01 2008
    Nơi ở
    UIT
    Bài viết
    129

    Có lẽ bạn đọc nhanh quá nên hơi bị nhầm
    DLL nếu nạp run-time thì phải xuất ra C-Interface mới dùng được. Nếu không có extern "C" thì mỗi trình dịch nó mangle một kiểu thì loạn

    Chú ý thêm một chút về cách viết DLL là nên khai báo tường minh calling convention vì nếu dùng mặc định, trình dịch sẽ dùng __cdecl (có thể cấu hình lại compiler), nếu gặp hàm CALLBACK là có thể crash lên xuống (lỗi này người ko rành hệ thống là chào thua, ko biết sửa ). Hàm của bạn trong DLL chỉ dùng kiểu bình thường nên ko có vấn đề chi.

    DLL của bạn nên viết lại là :

    Code:
    #include <stdio.h>
    
    extern "C" __declspec(dllexport) void __cdecl Hello()
    {
        printf("Hello\n");
    }
    Xin bổ sung là nếu bạn sử dụng cdecl thì có thể nếu ai đó lập trình VB muốn sử dụng dll của bạn thì họ có thể gặp vấn đề không thể gọi hàm từ dll

  3. #3
    Ngày gia nhập
    01 2009
    Bài viết
    64

    extern "C"
    có nghĩa là khai báo 1 biến toàn cục ở ngoài của File,VD 1 File DLL được khai báo biến là extern "C" x; có nghĩa là nếu chương tình nào sử dụng đến biến x thì biến đó sẽ là biến toàn cục trong chương trình

  4. #4
    Ngày gia nhập
    01 2008
    Nơi ở
    UIT
    Bài viết
    129

    Trích dẫn Nguyên bản được gửi bởi cSharp Xem bài viết
    có nghĩa là khai báo 1 biến toàn cục ở ngoài của File,VD 1 File DLL được khai báo biến là extern "C" x; có nghĩa là nếu chương tình nào sử dụng đến biến x thì biến đó sẽ là biến toàn cục trong chương trình
    Cái này là quy tắc unmangle chứ không phải biến gì đâu

  5. #5
    Ngày gia nhập
    01 2009
    Bài viết
    64

    Khóa extern chủ yếu dùng trong các module C programming rất nhiều. Có 2 mục đich mà người ta dùng extern:
    1) Giả sử bạn declare một biến hoặc một hàm mà chỉ local trong module c file đó (không có declare trong header file, ví dụ file a.c), có nghĩa là bạn chỉ muốn biến đó hoặc hàm đó là biến hoặc hàm global của cái module a.c file mà thôi, bên ngoài hàm đó tuyệt nhiên không biết gì về mấy cái này. Thông thường thì ta declare nó trong một header file (như a.h) rồi những module khác có thể include a.h, và nó trở thành global với tất cả các modules. Declare biến/hàm local của một module là một hình thức data hiding (nếu không dùng OOD). Sau đó nếu ta muốn export biến/hàm này vô một module khác, thì ta phải dùng khóa extern trong header file (a.h). Làm như vậy nó an toàn hơn.

    2) Đôi khi khóa extern cũng được dùng trong C++. C++ compiler thông thường mangle những hàm declare trong tất cả các module, mà C không có mangle những hàm này. Do đó nếu ta muốn pha trộn giữa hàm C++ với với hàm C thì ta phải dùng khóa exern như sau:

    #if defined(__cplusplus)
    extern "C"
    void funcA();
    void funcB();
    #endif // defined(__cplusplus)

  6. #6
    Ngày gia nhập
    01 2008
    Nơi ở
    UIT
    Bài viết
    129

    Mặc định name mangling trong C và C++ tác dụng thế nào?

    Trường hợp mà howto đang đề cập chỉ là mangle chứ ko đề cập đến extern variables.
    Mặt khác bạn ấy nói đích thị extern "C", nên ko cần nói đến extern variables làm gì

    Xin sửa lại một tí :

    Code:
    #if defined(__cplusplus)
    extern "C" {
        void funcA();
        void funcB();
    }
    #endif // defined(__cplusplus)
    Đã được chỉnh sửa lần cuối bởi Hok_bik_zi : 08-02-2009 lúc 09:17 AM.

  7. #7
    Ngày gia nhập
    11 2008
    Bài viết
    78

    Oh em đã coi kĩ lại, quả thực là phải unmangle
    Nhưng tại sao trong kĩ thuật hook, các filter functions không hề unmangle mà vẫn có thể gọi được

  8. #8
    Ngày gia nhập
    09 2006
    Bài viết
    711

    Cần phân biệt giữa dllspec(dllexport) và dùng def file.
    Dùng tool để xem hàm Hello trong dll của cậu được export ra với name đầy đủ là gì.
    Toàn bộ Win32 API đều được export = def file.

  9. #9
    Ngày gia nhập
    11 2008
    Bài viết
    78

    Cho em hỏi dùng def file và __declspec(dllexport) thì cái nào lợi hơn ?
    Dùng tools nào để xem hàm export trong dll ạh ?

  10. #10
    Ngày gia nhập
    09 2006
    Bài viết
    711

    Tới giờ tui vẫn dùng def file. Trong bộ VS có depends.exe.

Các đề tài tương tự

  1. Làm Chữ chạy trên form C# như thẻ <marquee> trong HTML thế nào?
    Gửi bởi magnet241 trong diễn đàn Thắc mắc lập trình C#
    Trả lời: 6
    Bài viết cuối: 05-04-2012, 11:55 AM
  2. In thẻ,hóa đơn từ các textbox,combobox,datetimepicker trong form C# như thế nào?
    Gửi bởi snoit trong diễn đàn Thắc mắc lập trình C#
    Trả lời: 2
    Bài viết cuối: 04-04-2012, 03:13 PM
  3. Game Tạo Form trong suốt trong C# tựa game Thần Võ như thế nào?
    Gửi bởi tocvang_pro trong diễn đàn Thắc mắc lập trình C#
    Trả lời: 5
    Bài viết cuối: 21-09-2011, 04:21 PM
  4. Sử lí như thế nào khi nhập rất chậm trong trình xoạn thảo trong devC
    Gửi bởi toansvcn trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 13
    Bài viết cuối: 23-05-2011, 10:04 PM
  5. Code tìm kiếm trong cây nhị phân trong C++. Lỗi chỉ tìm được từ đầu tiên trong file thôi sửa thế nào?
    Gửi bởi elvish trong diễn đàn Thảo luận, góp ý code C/C++ của bạn
    Trả lời: 1
    Bài viết cuối: 11-04-2010, 09:43 PM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn