2011-06-17 33 views
5

Tôi có một chương trình C và tôi đã tạo một tệp DLL. Tôi đang sử dụng Windows Vista và Visual C++.Truy cập một phương thức từ một DLL từ chương trình C#

Bây giờ tôi cần truy cập một phương thức từ DLL đó, từ phương thức Main() của mã C#. Các bước làm như thế là gì?

Cho đến giờ tôi đã thêm tệp DLL làm tham chiếu, sau đó tôi nên làm gì?

này chỉ là một ví dụ:

int main1(void) { 
    prinf("Hello World"); 
} 

Xin lưu ý rằng lớp này cũng làm cho chúng ta về chức năng lib khác, nhưng tôi đã có thể tạo ra thành công một DLL ra khỏi nó. (Tôi không biết nếu điều này có liên quan)

Bây giờ tôi cần truy cập phương thức này từ C# Main();

[STAThread] 
static void Main() 
{ 
    // I need to call that main1() method here 

    Application.EnableVisualStyles(); 
    Application.SetCompatibleTextRenderingDefault(false); 
    Application.Run(new Form1()); 
} 
+0

Không thể thêm tham chiếu đến tệp DLL gốc C. Rõ ràng bạn không sử dụng một dll C thực, có thể là một C++/CLI. Không có gì đặc biệt là cần thiết trong trường hợp đó, các khai báo "lớp ref" bạn tạo ra công khai có sẵn trực tiếp trong một chương trình C#. –

+0

Vâng, đó là một dự án C++/CLI. Dựa trên câu trả lời của bạn có vẻ như nó có thể được thực hiện trực tiếp, bằng cách nói 'lớp ref' bạn có nghĩa là lớp C của tôi? và làm cách nào để công khai? Các bước tôi đã làm cho đến nay, thêm dll Làm tham chiếu và thêm câu lệnh sau 'using detect.h' và cố gắng truy cập nó từ phương thức C#, Main() như; 'detect.the_method_i_need()', nhưng nó không hoạt động như thế. HELP – illep

Trả lời

5

Xem using a class defined in a c++ dll in c# code trong đó có một câu trả lời được chấp nhận tuyệt vời. Và như Hans Passant đã viết trong các bình luận, bạn không thể thêm một DLL gốc làm tham chiếu đến một dự án C#.

Khi tôi đề cập đến một trong các DLL gốc của riêng mình, tôi thường thêm phụ thuộc giữa dự án C# và dự án tạo DLL gốc hoặc tôi thêm DLL dưới dạng tệp nội dung được liên kết trong dự án C#, như như vậy:

  1. Nhấp chuột phải vào dự án và chọn Thêm> Mục hiện tại.
  2. Duyệt và chọn tệp DLL bạn muốn nhưng không nhấp vào Thêm.
  3. Nhấp vào mũi tên nhỏ ở bên phải của Thêm và chọn Thêm làm liên kết.
  4. Chọn tệp DLL hiện xuất hiện trong dự án C# của bạn và chuyển đến thuộc tính của nó.
  5. Đảm bảo bạn có Build Action được đặt thành Nội dung.

này sẽ sao chép DLL vào thư mục bin\Debug của C# dự án và chắc chắn rằng, nếu bạn một lần quyết định để tạo ra một dự án Setup, bạn có thể dễ dàng tham khảo tất cả file nội dung và bao gồm chúng trong Microsoft Installer gói.

Bây giờ, để có thể xem các hàm được viết trong DLL gốc của bạn, bạn phải chăm sóc xuất chúng (xem Exporting C Functions for Use in C or C++ Language ExecutablesExporting from a DLL Using __declspec(dllexport)). Vì vậy, bạn phải thêm một khối extern "C" xung quanh tờ khai chức năng của bạn (Tôi giả sử bạn đã viết mã của mình trong một số .cpp file nguồn và điều này có nghĩa rằng trình biên dịch sẽ phát ra đọc sai tên hàm nếu bạn không khai báo chúng như là extern "C"):

extern "C" 
{ 
    __declspec (dllexport) void __cdecl Foo(const char* arg1); 
} 

... 

void Foo(const char* arg1) 
{ 
    printf ("Hello %s !", arg1); 
} 

Trang trí __declspec (dllexport) có nghĩa là trình biên dịch/mối liên kết sẽ phải thực hiện chức năng có thể nhìn thấy từ bên ngoài của DLL. Và __cdecl xác định cách các thông số sẽ được chuyển cho hàm (cách "C" chuẩn làm việc này).

Trong mã # C của bạn, bạn sẽ phải tham khảo các phương pháp xuất khẩu của DLL của bạn:

class Program 
{ 
    [DllImport("mydll.dll")] 
    internal static extern void Foo(string arg1); 

    static void Main() 
    { 
     Program.Foo ("Pierre"); 
    } 
} 

Bạn nên đọc Platform Invoke Tutorial mang đến cho tất cả các chi tiết đẫm máu.

+0

Xin chào @Pierre, tôi đã làm theo các bước của bạn và tôi không chắc chắn cách đặt ** Nội dung ** là ** Build Action **, tuy nhiên, khi tôi biên dịch mã, tôi không tìm thấy bản sao của DLL của mình _bin \ Debug_ của dự án C# của tôi. Hy vọng bạn có thể giúp tôi ở đây, và bạn cũng có thể cho tôi biết làm thế nào để truy cập một phương pháp của DLL mà tôi đã thêm từ phương thức Main() của dự án C# của tôi. – illep

+1

@illep: Nhấp vào tệp DLL trong dự án C#, nhấn F4. Trong cửa sổ công cụ Thuộc tính, dòng đầu tiên được gắn nhãn "Build Action". Nhấp vào bên phải của nó, chọn "Nội dung". Đảm bảo rằng "Sao chép vào thư mục đầu ra" được đặt thành một trong các tùy chọn sao chép. –

+0

@illep: Chỉnh sửa bài đăng của bạn và thêm mẫu mã C mà bạn muốn có quyền truy cập vào. Bạn phải đảm bảo rằng hàm C của bạn được trang trí đúng với chỉ thị xuất DLL. –

0

Bạn đang tìm kiếm Platform Invoke và thuộc tính [DllImport].

+0

Tôi đã làm như sau/n '[DllImport (" detect.dll ")] nội bộ static extern int main1(); ' ,' detect.dll' là tên của DLL mà tôi đã tạo. main1() là phương pháp tôi đang tìm cách thực thi từ mã C# của tôi. Bây giờ, từ mã C# tôi gọi là main1(); phương pháp và tôi nhận được một lỗi ** DLL không tìm thấy ngoại lệ **, nhưng DLL nằm trong thư mục _bin \ Debug_. Làm cách nào để tôi giải quyết vấn đề này. lưu ý: Đây là cách tôi thêm DLL của tôi, R-Click vào dự án và thêm tham khảo -> chọn DLL – illep

0

Bạn cần đọc lên trên P/Gọi aka pinvoke aka "Nền tảng Gọi":

http://msdn.microsoft.com/en-us/library/aa288468(v=vs.71).aspx

+0

Có, tôi đã đi qua một số hướng dẫn về điều này, nhưng tôi không hiểu những gì ** public static extern ** có nghĩa. tôi không thể chỉnh sửa mã C của mình đã được viết bằng cách sử dụng hình ảnh C++. anyway tôi có mã như một tập tin DLL. ví dụ xem xét đoạn mã sau; 'void main() { printf (" HELLO WORLD "); } ' ở trên là mã C của tôi, và bây giờ là một DLL, làm thế nào để tôi truy cập chính này() từ phương thức C# Main() của tôi. tôi về cơ bản muốn thực hiện những gì trong đó chính() (của mã c của tôi). Trợ giúp! – illep

+0

@illep: nếu bạn không thể sửa đổi DLL của mình, thì bạn không còn may mắn nữa - các chức năng phải được xuất để chúng có thể được truy cập từ thế giới bên ngoài. Nếu DLL của bạn là một EXE trong ngụy trang (với chức năng 'main' đang hoạt động), bạn có thể thực thi DLL đó bằng cách sử dụng' System.Diagnostics.Process.Start', tôi đoán vậy. –

+0

@Pierre Có, tôi đã thử điều đó, nhưng tôi không muốn Console mở. Có cách nào để tránh điều này ? – illep

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