2012-05-03 58 views
10

Xin chào Tôi có một DLL có hàm mà tôi cần gọi. Chữ ký là:Gọi một dll c từ C++, C# và ruby ​​

const char* callMethod(const char* key, const char* inParams); 

Nếu tôi sử dụng ruby ​​tất cả mọi thứ hoạt động tốt:

attach_function :callMethod, [:string, :string], :string 

Nếu tôi sử dụng C++ hoặc C# tôi nhận được stack overflow!?

C#:

[DllImport("DeviceHub.dll", CallingConvention = CallingConvention.Cdecl)] 
private unsafe static extern IntPtr callMethod(
    [MarshalAs(UnmanagedType.LPArray)] byte[] key, 
    [MarshalAs(UnmanagedType.LPArray)] byte[] inParams 
); 

System.Text.UTF8Encoding encoding = new UTF8Encoding(); 
IntPtr p = callMethod(encoding.GetBytes(key), encoding.GetBytes(args)); // <- stack overflow here 

C++:

extern "C" 
{ 
typedef DllImport const char* ( *pICFUNC) (const char*, const char*); 
} 
HINSTANCE hGetProcIDDLL = LoadLibrary(TEXT("C:\\JOAO\\Temp\\testedll\\Debug\\DeviceHub.dll")); 
FARPROC lpfnGetProcessID = GetProcAddress(HMODULE (hGetProcIDDLL),"callMethod");*  pICFUNC callMethod; 
callMethod = (pICFUNC) lpfnGetProcessID; 
const char * ptr = callMethod("c", "{}"); 

Tôi đã thử nhiều biến thể để gọi chức năng: WINAPI, PASCAL, stdcall, fastcall, ... không có gì hoạt động.

DLL chưa được tạo bởi tôi và tôi không kiểm soát được.

Có ai có thể giúp tôi với bất kỳ đề xuất nào không !?

+0

Bạn có thể xem câu hỏi của mình để có ý tưởng. Đây là một [link] [1] [1]: http://stackoverflow.com/questions/7153521/pass-multi-dimensional-array-from-managed-code-to-unmanaged-code –

+2

Tại sao bạn không sử dụng 'chuỗi' cho các loại của hai tham số trong C#? – Ove

+0

Hãy tin tôi là tôi đã tìm kiếm rất nhiều ... :). Tôi cũng đã thử với dây nhưng để tránh C# vấn đề tôi cũng đã thử nghiệm với cũ tốt c + + và vẫn tràn ngăn xếp! – Joao

Trả lời

-5

Tràn ngăn xếp Ngoại lệ là một lỗi được đặt trong ngôn ngữ microsoft để ngăn chặn đệ quy vô hạn và ngăn các chương trình không tương thích tương tác với nhau. Nếu phương pháp dll của bạn sử dụng đệ quy, hãy thử viết lại nó với lặp lại. Nếu không, hãy làm như Ove nói, và thử với dây. Nếu nó vẫn không hoạt động, Google cho một loại tương thích. Đó là tất cả những gì tôi có thể nói mà không biết phương pháp thực tế.

+0

"* Stack Overflow Exception là một lỗi được đặt trong các ngôn ngữ microsoft để ngăn chặn đệ quy vô hạn, và để ngăn các chương trình không tương thích tương tác với nhau. *" Bạn lấy ý tưởng này ở đâu?Bạn có thể tràn ngăn xếp trên bất kỳ nền tảng nào tôi biết ... – ildjarn

+0

Đơn giản, tôi chỉ đọc nó trên trang web của microsoft trong khi googleing giải pháp cho vấn đề của riêng tôi. Giải pháp đã thay đổi nó thành lặp lại. – m12

+0

Quan điểm của tôi là nó không theo bất kỳ cách nào cụ thể cho các ngôn ngữ/nền tảng của Microsoft, cũng như ở đó để ngăn các chương trình không tương thích tương tác với nhau (đôi khi _caused by_ các chương trình không tương thích tương tác với nhau). – ildjarn

1

Đây chỉ là một ý tưởng nhưng AFAIK này có thể là một vấn đề với null- các chuỗi bị chấm dứt, const char* myvar bị vô hiệu nhưng một mảng byte thì không. Mọi thứ bạn cần làm là thay đổi cuộc gọi thành ...(String a, String b) và sắp xếp chúng theo số LPStr.

+0

cùng một điều! System.stackoverflow exception – Joao

+0

@Joao Tôi chắc chắn rằng lỗi không được tạo bởi chính cuộc gọi (tôi chắc chắn cuộc gọi ở trên là chính xác), có thể có lỗi trong phương thức bạn gọi vì chồng -overflow được tạo ra khi thực hiện nhiều dữ liệu trên stack, điều này có thể có nhiều lý do. –

+0

có bạn đúng. nhưng điều làm tôi bực mình là việc ruby ​​hoạt động ... Tôi gật đầu không biết Ruby rất tốt và tôi đang xem xét khả năng có một số khác biệt cơ bản giữa cuộc gọi ruby ​​và C++ hoặc cuộc gọi C# làm cho điều này xảy ra. Một vấn đề khác có thể là một số tùy chọn trình biên dịch. – Joao

0

tôi thấy không có lý do tại sao bạn không nên thay đổi cuộc gọi của bạn để

[DllImport("DeviceHub.dll", CallingConvention = CallingConvention.Cdecl)]
private unsafe static extern string callMethod(
string key,
string inParams
);

Bạn cần phải gửi con trỏ, không thực tế giá trị/byte để hàm.
Tôi luôn sử dụng mapping này khi tạo chuyển đổi loại cho các cuộc gọi hàm gốc.
Tương tự áp dụng cho mã C++, bạn cần tạo các biến với nội dung và gọi hàm đó.

+0

điều tương tự! system.stackoverflow exception – Joao

+0

Bạn có thể hiển thị mã đã thay đổi của mình không? Ngoài ra tôi sẽ sử dụng http://www.dependencywalker.com/ để kiểm tra các vấn đề phụ thuộc. – weismat

+0

Tôi đã thực hiện chính xác như đoạn mã của bạn và cũng đã thử với [MarshalAs (UnmanagedType.LPStr)]. Cách tôi gọi là response = callMethod (key, args); trong đó khóa và arg là loại chuỗi – Joao

Các vấn đề liên quan