P / Invoke và .NET Target Framework [trùng lặp]

Jan 22 2021

Vấn đề này đang đẩy tôi vào chân tường ... Chỉ nói.

Công ty của tôi có một thư viện C ++ kế thừa và tôi được giao nhiệm vụ tạo một trình bao bọc .NET.
Tôi không có kinh nghiệm về C ++ hoặc P / Invoke nên để bắt đầu, tôi đang thử một phương pháp đơn giản.

Tôi đã đọc tài liệu chính thức và tôi cũng đã tìm thấy một hướng dẫn hay .
Tuy nhiên, tôi đã phát hiện ra rằng khung công tác .NET đích của ứng dụng tiêu thụ tạo ra sự khác biệt.
Mã P / Invoke từ hướng dẫn hoạt động tốt nhưng tôi nhận thấy rằng anh ấy đang nhắm mục tiêu Hồ sơ máy khách .NET Framework 4 .
Nếu tôi đặt các điểm ngắt thì chúng bị tấn công và mọi thứ hoạt động như mong đợi, nếu tôi nhắm mục tiêu khung cao hơn 4 thì chương trình bị treo mà không có ngoại lệ.

Tôi có một phương thức thực sự đơn giản được định nghĩa trong C ++:
framework.h

extern "C" {
    API char* SayHello();
}

dllmain.cpp

char* SayHello() {
    return (char*)"Hello";
}

C#

        [DllImport("PInvokeTest.dll")]
        public static extern string SayHello();

(Tôi đã thử thiết lập CallConvention và CharSet trên thuộc tính trong các kết hợp khác nhau, tôi đã quản lý để có được các ký tự Trung Quốc, nhưng không có gì hoạt động cao hơn Khung 4)

Dự án C ++ của tôi đã API=__declspec(dllexport)đặt Định nghĩa tiền xử lý và Quy ước gọi là _stdcall (\Gz)(Tôi cũng đã thử _cdecl).
Dự án C # hoạt động tốt trên Framework 4 , khi tôi thay đổi thành bất kỳ thứ gì ở trên thì nó sẽ thoát ra mà không có ngoại lệ.
Tôi cũng đã tìm thấy GUI phụ thuộc đang hiển thị cho tôi rằng SayHellothực sự có ở đó.

Công ty của chúng tôi sử dụng 4.6.1, tôi cũng đã xem qua bài viết này dẫn tôi đến PInvokeStackImbalance nhưng điều đó không làm được gì trong trường hợp của tôi.

Mọi sự trợ giúp sẽ rất được trân trọng.
Tôi có thể tạo repo GitHub tạm thời nếu cần.

Trả lời

LukeTO'Brien Jan 22 2021 at 19:50

Bây giờ tôi biết đó là một vấn đề chuỗi, tôi đã tìm kiếm một chút và tôi đã tìm thấy câu hỏi SO này .
Vì vậy, cuối cùng tôi đã sử dụng BSTRcách tiếp cận.

BSTR SayHello() {
    return ::SysAllocString(L"Hello");
}
        [DllImport("DBReplicator.Lib.dll")]
        [return: MarshalAs(UnmanagedType.BStr)]
        public static extern string SayHello();

... Tuy nhiên, tôi vẫn không biết làm cách nào để có được các ký tự Trung Quốc.