2014-05-12 15 views
8

Có vẻ như phải có câu hỏi trùng lặp, nhưng tôi chưa thể tìm thấy câu hỏi đó.Chuyển int bằng tham chiếu từ C++/CLI tới C#

Tôi đang viết một cây cầu để cho phép một chương trình C cũ truy cập một số đối tượng C#. Cây cầu được viết bằng C++/CLI.

Trong một trường hợp có một hàm C# đó là định nghĩa là:

public static string GetNameAndValue(out int value); 

C My ++/CLI wrapper chức năng:

char* GetNameAndValue(int* value); 

Đó là đủ dễ dàng để gọi từ C. Nhưng làm cách nào để gọi phương thức C# từ C++/CLI?

đầu tiên tôi đã cố gắng rõ ràng:

String^str; 
str = TheObject::GetNameAndValue(value); 

Đó mang lại cho tôi lỗi C2664: Không thể chuyển đổi thông số 2 từ 'int *' thành 'int%'.

OK, sau đó, khoảng GetNameAndValue(%value)? Điều đó mang lại cho tôi lỗi C3071: toán tử '%' chỉ có thể được áp dụng cho một cá thể của một lớp ref hoặc một kiểu giá trị.

Đủ công bằng. Vì vậy, nếu tôi tạo ra một int tôi có thể vượt qua nó với % ??

int foo; 
str = TheObject::GetNameAndValue(%ix); 

Không súc sắc. C3071 một lần nữa. Mà tôi thấy kỳ lạ bởi vì int chắc chắn một loại giá trị. Hoặc là nó?

Phải có một số kết hợp ma thuật của%, ^, &, hoặc một số khác khiêu dâm sẽ làm những gì tôi muốn, nhưng sau khi thề tại điều này trong 30 phút tôi stumped. Và tìm kiếm các kết hợp khác nhau của C++/CLI và C# chủ yếu cung cấp thông tin về cách gọi C++ từ C#.

SO, câu hỏi của tôi: Làm thế nào để bạn vượt qua một int từ C++/CLI đến một phương pháp C# mà mong đợi một out int (hoặc ref int, nếu tôi phải)?

+1

Bạn đã có những điều ngược lại. C++/CLI là khá vô dụng để cho phép một chương trình C gọi một phương thức C#.Nó là một phần mở rộng ngôn ngữ đã được thực hiện để đi theo cách khác, từ mã được quản lý để mã nguồn gốc. Chạy mã được quản lý từ một chương trình gốc đòi hỏi nhiều vũ khí lớn hơn, nó phải nạp và khởi tạo CLR trước. Sẽ mất hơn 30 phút để sắp xếp. –

+1

@ HansPassant: Đó không phải là trải nghiệm của tôi trong thời gian ngắn tôi đã làm việc với điều này. Chương trình C của tôi gọi một DLL đã được biên dịch bằng C++/CLI, mà lần lượt gọi mã C# trong một assembly khác. Hoạt động khá tốt. Như tôi đã hiểu, DLL C++/CLI tải thời gian chạy. Dù thế nào đi nữa, tôi đã có thể lấy thông tin từ mã C# về mã C. –

+0

C++/CLI hỗ trợ __declspec (dllexport), đó là kịch bản duy nhất tôi có thể nghĩ đến nơi bạn có thể có may mắn với nó. Cùng một ý tưởng như hack [DllExport] của Giesecke. Khi được đăng, câu hỏi của bạn có ý nghĩa rất ít đối với tôi và các vấn đề bạn đang gặp là hoàn toàn bình thường. Chúc may mắn với điều đó. –

Trả lời

5

C#:

class MyClass 
{ 
    public static string GetNameAndValue(out int value); 
} 

C++/CLI:

int value; 
String^ x = MyClass::GetNameAndValue(value); 

C++/CLI wrapper:

CString GetNameAndValue(int* value) 
{ 
    String^ x = MyClass::GetNameAndValue(*value); 
    return CString(x); 
} 

C++/CLI wrapper 2:

CString GetNameAndValue(int& value) 
{ 
    String^ x = MyClass::GetNameAndValue(value); 
    return CString(x); 
} 

Điều này cũng giống với C# "ref".

+0

Đó là * hoàn toàn * không hiển nhiên! Vì vậy, khi tôi làm 'MyClass :: GetNameAndValue (* value)', trình biên dịch sẽ tự động marshaling nó như một cái gì đó như '[out] System :: Int32'? Nó sẽ đưa tôi một chút để kiểm tra điều này, nhưng nếu nó hoạt động tôi sẽ chấp nhận câu trả lời. –

+2

Nó giống như gọi C++: "void x (int &);" bằng cách truyền biến "int v;". Cơ chế là như nhau. Không có diễn viên. Đối với trình biên dịch, nguyên mẫu mong muốn giống như nguyên mẫu được xác định. –

+0

Hơn nữa, sự khác biệt duy nhất giữa ref và out là bạn buộc phải gán biến bên trong phương thức. Nếu không, bạn có thể nghĩ về ref như C++ &. Bằng cách này tôi sử dụng C++, C++/CLI, C# trong một thời gian và thực sự không cần sử dụng ký hiệu%, bạn có thể định nghĩa nó tương đương trong C# hoặc C++. Vì vậy, trong C++/CLI, biểu tượng loại tham chiếu bổ sung duy nhất còn lại để quan tâm là ^. –

0

Tôi biết điều này đã được trả lời nhưng chỉ để làm rõ những gì trình biên dịch đã đề xuất với "C2664: Không thể chuyển đổi tham số 2 từ 'int *' thành 'int%'".
Tôi nghĩ rằng nó muốn điều này (C++/CLI):

int a=5 
int% foo=a; 
str = TheObject::GetNameAndValue(foo); 
+0

Không thực sự. Đó là tham số tham chiếu và có thể liên kết với một giá trị. Bạn không cần tạo tham chiếu khác trong trình gọi ... và tham số ** sẽ không ** liên kết với tham chiếu của người gọi. –

+1

Toàn bộ điểm và mục đích của bài đăng của tôi là rõ ràng và rõ ràng, không có thuật ngữ lạ mắt. Bạn tất nhiên là đúng, nhưng rất học thuật. Tôi nghĩ rằng những ví dụ đơn giản thậm chí tầm thường thì tốt hơn. Điều này thực sự là vấn đề với MSDN: nó được viết theo một cách rất khoa học, vì vậy nó phản trực giác và khó nắm bắt trong một thời gian ngắn. Đó là lý do tại sao chúng tôi có các trang web như thế này. – Pifcnt

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