P / Invoke ve .NET Target Framework [çoğaltma]

Jan 22 2021

Bu mesele beni duvara itiyor ... Sadece söylüyorum.

Şirketimin eski bir C ++ kitaplığı var ve bir .NET sarmalayıcı oluşturmakla görevlendirildim.
C ++ veya P / Invoke deneyimim yok, bu yüzden başlamak için basit bir yöntem deniyorum.

Resmi belgeleri okudum ve ayrıca güzel bir eğitim buldum .
Ancak, tüketen uygulamanın hedef .NET çerçevesinin bir fark yarattığını keşfettim.
Öğreticideki P / Invoke kodu iyi çalışıyor ancak .NET Framework 4 İstemci Profili'ni hedeflediğini fark ettim .
Kırılma noktaları yerleştirirsem, vurulurlar ve her şey beklendiği gibi çalışır, 4'ten daha yüksek bir çerçeveyi hedeflersem program istisnasız çöker.

C ++ 'da tanımlanmış gerçekten basit bir yöntemim var:
framework.h

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

dllmain.cpp

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

C#

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

(CallingConvention ve CharSet'i öznitelik üzerinde farklı kombinasyonlarda ayarlamayı denedim, Çince karakterleri almayı başardım, ancak Çerçeve 4'ten daha yüksek hiçbir şey çalışmıyor)

C ++ projemde Ön İşlemci API=__declspec(dllexport)Tanımları ayarlandı ve Çağrı Kuralı _stdcall (\Gz)(_cdecl'i de denedim).
C # projesi Framework 4'te iyi çalışıyor , bunun üzerine herhangi bir şeye değiştirdiğimde istisnasız olarak çıkıyor.
Ayrıca bana gerçekten orada olduğunu gösteren Bağımlılıklar GUI'sini de buldum SayHello.

Şirketimiz 4.6.1 kullanıyor, ben de beni PInvokeStackImbalance'a götüren bu makaleye rastladım ama bu benim durumumda hiçbir şey yapmıyor.

Herhangi bir yardım çok takdir edilecektir.
Gerekirse geçici bir GitHub deposu oluşturabilirim.

Yanıtlar

LukeTO'Brien Jan 22 2021 at 19:50

Şimdi bunun bir dizi sorunu olduğunu bildiğime göre biraz arama yaptım ve bu SO sorusunu buldum .
Sonunda BSTRyaklaşımı kullandım .

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

... Yine de Çince karakterleri nasıl elde ettiğimi bilmiyorum.