2010-06-16 50 views
8

Có thể gọi CLR DLL (một ví dụ được tạo bằng C#) từ mã C++ không được quản lý?Có thể gọi một DLL được quản lý từ C++ không được quản lý?

Tôi cần một DLL không được quản lý để gọi vào nó bằng cách nào đó, thậm chí thông qua một số quy trình C++ proxy được xây dựng với C++/CLI?

+2

Bạn có thể quấn rằng dll quản lý thành một thực thi là một ứng dụng giao diện điều khiển và nhận các đối số dòng lệnh, trong khi đưa ra kết quả của nó cho 'stdout'. Sau đó bạn có thể gọi nó như bạn sẽ làm bất kỳ exe nào khác. Không lý tưởng, nhưng có thể làm việc. Tôi hy vọng bạn không sử dụng nhiều chủ đề, bởi vì tôi không biết nếu điều này sẽ làm việc sau đó. –

+1

Bạn đã tự trả lời. Viết một proxy trong C++/CLI (hoặc C++. Net hoặc được quản lý C++ hoặc cách nó được gọi ngày nay), sau đó gọi proxy này từ mã C++ không được quản lý của bạn. – Patrick

+0

có thể điều này sẽ giúp: http://stackoverflow.com/questions/1058897/can-c-cli-be-used-to-call-net-code-from-native-c-applications – smerlin

Trả lời

6

DLL CLR sẽ phải được xây dựng như một cụm hiển thị COM. Nếu bạn có quyền kiểm soát C#, đó là một bản dựng lại đơn giản, nếu không, sẽ không thể sử dụng trực tiếp nhiều.

+0

@ Hamish, cẩn thận để xây dựng? –

+0

Đã thêm "... để sử dụng trực tiếp". Nếu không thì ý nghĩa là sai, xin lỗi. – SWeko

+0

@SWeko: Luôn có đảo ngược PInvoke. Vì vậy, nó không phải là không thể. – Aamir

5

@SWeko cung cấp cho bạn câu trả lời hay nhất nếu bạn có thể sửa đổi DLL gốc và mã không được quản lý của bạn có thể dựa vào việc có quyền truy cập vào căn hộ COM (hoặc chủ đề riêng của nó với ::CoInitialize() gọi hoặc chuỗi gọi của mã không được quản lý căn hộ, chung cư).

Nếu đó không phải là trường hợp, thì giải pháp tốt nhất là tạo một "C++ DLL" được quản lý dưới dạng trình bao bọc trên assembly C# được quản lý. Nó được gọi là C++/CLI. Bạn có thể trưng ra các hoạt động API C không được quản lý và bên trong việc thực hiện các hoạt động đó, ủy quyền cho các API được quản lý. Nó hoạt động khá tốt và không giống như gọi API COM, không có vấn đề ái lực chủ đề.

4

Tôi không chắc nó có phù hợp không, nhưng có lẽ "Reverse PInvoke" là một tùy chọn.

Nếu trước tiên bạn có thể gọi từ C# sang C++, bạn có thể cung cấp đại biểu .net cho C++ nơi có thể sử dụng làm con trỏ hàm. Sau đó bạn có thể gọi từ C++ của bạn đến C# bằng cách sử dụng con trỏ hàm đó.

public delegate int Read(int target); 
[DllImport("yourC++.dll")] 
static extern void RegisterRead(Read x); 
Read m_Read = new Read(yourClass.Read); 

RegisterRead(m_Read); 

Có thể có một số thủ thuật với GC thu thập các đại biểu sớm, bất cứ điều gì lớp có các đại biểu có thể cần phải được ghim nếu nó không phải là chỉ được sử dụng immediatly trong RegisterRead

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