trong dự án tiếp theo của tôi, tôi muốn triển khai GUI cho mã đã tồn tại trong C++. Kế hoạch của tôi là bọc phần C++ trong một tệp DLL và triển khai GUI trong C#. Vấn đề của tôi là tôi không biết làm thế nào để thực hiện một cuộc gọi lại từ DLL không được quản lý vào mã C#. Tôi đã thực hiện một số phát triển trong C# nhưng giao tiếp giữa mã được quản lý và không được quản lý là mới đối với tôi. Ai có thể cho tôi một số gợi ý hoặc lời khuyên đọc hoặc một ví dụ đơn giản để bắt đầu từ đâu? Thật không may tôi không thể tìm thấy bất cứ điều gì hữu ích.Làm cách nào để triển khai giao diện gọi lại từ DLL không được quản lý đến ứng dụng .net?
Trả lời
Bạn không cần sử dụng Marshal.GetFunctionPointerForDelegate(), P/Invoke marshaller thực hiện tự động. Bạn sẽ cần phải khai báo một đại biểu ở phía C# có chữ ký tương thích với khai báo con trỏ hàm trên phía C++. Ví dụ:
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
class UnManagedInterop {
private delegate int Callback(string text);
private Callback mInstance; // Ensure it doesn't get garbage collected
public UnManagedInterop() {
mInstance = new Callback(Handler);
SetCallback(mInstance);
}
public void Test() {
TestCallback();
}
private int Handler(string text) {
// Do something...
Console.WriteLine(text);
return 42;
}
[DllImport("cpptemp1.dll")]
private static extern void SetCallback(Callback fn);
[DllImport("cpptemp1.dll")]
private static extern void TestCallback();
}
Và C++ mã tương ứng sử dụng để tạo ra các DLL không được quản lý:
#include "stdafx.h"
typedef int (__stdcall * Callback)(const char* text);
Callback Handler = 0;
extern "C" __declspec(dllexport)
void __stdcall SetCallback(Callback handler) {
Handler = handler;
}
extern "C" __declspec(dllexport)
void __stdcall TestCallback() {
int retval = Handler("hello world");
}
Đó là đủ để giúp bạn bắt đầu với nó. Có hàng triệu chi tiết có thể khiến bạn gặp rắc rối, bạn nhất định sẽ gặp phải một số vấn đề. Cách hiệu quả hơn nhiều để có được loại mã này là viết một trình bao bọc trong ngôn ngữ C++/CLI. Điều đó cũng cho phép bạn bọc một lớp C++, một cái gì đó bạn không thể làm với P/Invoke. Một hướng dẫn khá là available here.
Hãy xem điều này, Marshal.GetDelegateForFunctionPointer?
Xem Marshal.GetFunctionPointerForDelegate, sẽ cung cấp cho bạn một con trỏ hàm để gọi được quản lý (nghĩa là mã C#) từ mã không được quản lý.
P/Invoke có thể xử lý marshaling một đại biểu được quản lý với một con trỏ hàm. Vì vậy, nếu bạn tiếp xúc với API của đăng ký một cuộc gọi trở lại chức năng từ DLL của bạn và trong C# vượt qua một đại biểu cho chức năng đó.
Có ví dụ về MSDN khi thực hiện việc này với chức năng EnumWindows. Trong bài viết này phải cẩn thận chú ý đến dòng tại điểm 4 cho biết: Thao
Tuy nhiên, nếu chức năng gọi lại có thể được gọi sau khi trở về cuộc gọi, gọi quản lý phải thực hiện các bước để đảm bảo rằng đại biểu vẫn còn không được thu thập cho đến khi hàm gọi lại kết thúc. Để biết chi tiết thông tin về ngăn ngừa rác thải bộ sưu tập, hãy xem Interop Marshaling với Platform Invoke.
Điều gì đang nói là bạn cần đảm bảo rằng đại biểu của bạn không được thu thập rác cho đến sau khi mã được quản lý được gọi bằng cách giữ tham chiếu đến mã đó trong mã của bạn hoặc ghim nó.
+1 cho P/Invoke quan trọng - chỉ đảm bảo tính hợp lệ của con trỏ trong khi gọi - nếu bạn đang lưu vào bộ nhớ, bạn cần ghim nó (không thể nói để stashing tham chiếu , đáng ngờ, nhưng điều đó không có nghĩa là :-) –
- 1. Tiêm DLL được quản lý vào .net 4.0 Ứng dụng
- 2. Làm cách nào để gọi phương thức giao diện được triển khai rõ ràng từ PowerShell?
- 3. Thêm một con đường DLL bản địa để quản lý giao diện điều khiển ứng dụng
- 4. Gọi một cuộc gọi lại từ mã .NET được quản lý (khi tải mã được quản lý bằng COM)
- 5. Làm cách nào để sử dụng dll C# (được quản lý) mà tôi không có?
- 6. Hiệu suất của việc gọi mã không được quản lý từ mã được quản lý
- 7. Làm cách nào để triển khai gọi lại trong C++?
- 8. Có thể gọi một DLL được quản lý từ C++ không được quản lý?
- 9. Gọi hàm không được quản lý C/C++ DLL từ SQL Server 2008
- 10. Gọi lại C# từ DLL
- 11. Làm cách nào để triển khai giao diện trong Ada?
- 12. Làm cách nào để triển khai giao diện Iterable?
- 13. Tạo một C# DLL và sử dụng nó từ không được quản lý C++
- 14. Gói được quản lý với giao diện không được quản lý
- 15. Cách tốt nhất để gọi mã Managed .NET từ mã không được quản lý
- 16. Hủy bỏ cuộc gọi không được quản lý DLL
- 17. Làm cách nào để triển khai thủ tục được lưu trữ được quản lý mà không sử dụng Visual Studio?
- 18. Cách sử dụng mã được quản lý từ mã không được quản lý?
- 19. Làm thế nào để triển khai một ứng dụng giao diện điều khiển
- 20. Sử dụng dll C++ được quản lý từ C#
- 21. Làm cách nào để triển khai gọi lại trong PHP?
- 22. Gọi Shell32.dll từ .NET Windows Service
- 23. Cách đúng để triển khai ứng dụng giao diện điều khiển C#?
- 24. Làm cách nào để triển khai Giao diện có thể đếm được trong PHP?
- 25. Liên kết không được quản lý C++ DLL với quản lý C++ lớp thư viện DLL
- 26. .NET - triển khai ứng dụng khách WCF, không có app.config
- 27. Làm cách nào để có được Trình quản lý Cấu hình để tải cài đặt ứng dụng từ nhiều tệp?
- 28. Triển khai giao diện không tương thích
- 29. Giao diện triển khai C#
- 30. Làm cách nào để gọi giao diện CORBA từ C#?
Cảm ơn nobugz, tôi sẽ cố gắng sớm thôi. Và tôi hy vọng tôi sẽ không nhận được vào quá nhiều rắc rối ;-) – chrmue
hoạt động hoàn hảo cho tôi, cảm ơn một lần nữa! – chrmue