2010-12-28 14 views
14

Tôi đã cố gắng để xuất khẩu một chức năng kiểm tra đơn giản cho một dll để làm việc với một ứng dụng (FYI: mIRC) mà xác định quy ước gọi như:tên stdcall mangling sử dụng extern c và dllexport vs định nghĩa mô-đun (MSVC++)

int __stdcall test_func(HWND mWnd, HWND aWnd, char *data, char *parms, BOOL show, BOOL nopause) 

Bây giờ, để gọi điều này từ ứng dụng, tôi muốn sử dụng test_func nhưng tôi đã nhận thấy do mangling tên nó không đơn giản như tôi nghĩ.

Qua chủ đề tương tự ở đây tôi đã đi đến sự hiểu biết rằng việc sử dụng extern "C" kết hợp với __declspec (dllexport) là một phương pháp (hơi) loại bỏ mangling đến module định nghĩa (.def) equivelant. Tuy nhiên, khi sử dụng phương thức extern/dllexport, chức năng của tôi (ví dụ) luôn là số _test_func @ số trong khi .def đã xóa tất cả các xâu chuỗi theo yêu cầu để sử dụng với ứng dụng tôi cần để xuất sang.

Có thể ai đó vui lòng giải thích lý do vì sao đây là? Tôi chỉ tò mò về hai phương pháp. Cảm ơn!

Trả lời

11

dllexport/import được thiết kế để tự nạp lại, chứ không phải thư viện C cũ sử dụng GetProcAddress. Việc mangling bạn đã thấy là những gì mà tất cả các trình biên dịch của Microsoft đã thực hiện trong một thời gian dài cho các hàm __stdcall. Nhiều khả năng, mục tiêu của bạn hoặc mong đợi một hàm __cdecl, chứ không phải __stdcall, nhưng nếu không, bạn sẽ cần phải sử dụng một tệp .def để loại bỏ cụ thể tên.

12

extern "C" không có gì để làm với stdcall: nó chỉ tuyên bố rằng mang tên C++ mangling (còn gọi là liên kết kiểu an toàn; bao gồm thông tin kiểu trong tên biểu tượng) là vô hiệu hóa. Bạn cần phải sử dụng nó độc lập cho dù bạn sử dụng C gọi quy ước hoặc stdcall gọi quy ước.

Trong quy ước gọi hàm stdcall, callee xóa các tham số khỏi ngăn xếp. Để làm cho an toàn, tên được xuất chứa số byte mà callee sẽ xóa khỏi ngăn xếp.

Nếu ứng dụng bạn đang xuất để yêu cầu không có hậu tố @number được thêm vào tên, điều đó có thể có nghĩa là nó dự kiến ​​quy ước gọi điện C. Vì vậy, bạn nên ngừng khai báo hàm là __stdcall. Khi bạn khai báo nó là declspec(dllexport), bạn sẽ nhận được một tên undecorated trong DLL.

Trong tệp DEF, bạn có thể gọi hàm bất cứ điều gì bạn muốn; không thực hiện kiểm tra bổ sung.

+15

chức năng api của Windows là stdcall nhưng không có @number và trên Windows, đây là cách thực hành tiêu chuẩn để thực hiện theo cách này. –