P / Invoke y .NET Target Framework [duplicado]

Jan 22 2021

Este problema me está volviendo loco ... Solo digo.

Mi empresa tiene una biblioteca C ++ heredada y se me ha encomendado la tarea de crear un contenedor .NET.
No tengo experiencia en C ++ o P / Invoke, así que para empezar estoy probando un método simple.

He leído la documentación oficial y también he encontrado un bonito tutorial .
Sin embargo, he descubierto que el marco .NET de destino de la aplicación consumidora marca la diferencia.
El código P / Invoke del tutorial funciona bien, pero he notado que está apuntando a .NET Framework 4 Client Profile .
Si coloco puntos de interrupción, se activan y todo funciona como se esperaba, si apunto a un marco superior a 4, el programa se bloquea sin excepción.

Tengo un método realmente simple definido en C ++:
framework.h

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

dllmain.cpp

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

C#

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

(Intenté configurar CallingConvention y CharSet en el atributo en diferentes combinaciones, logré obtener caracteres chinos, pero nada funciona mejor que Framework 4)

Mi proyecto de C ++ tiene las API=__declspec(dllexport)Definiciones de preprocesador establecidas y la Convención de llamada es _stdcall (\Gz)(también probé _cdecl).
El proyecto C # funciona bien en Framework 4 , cuando cambio a algo anterior, simplemente sale sin excepción.
También encontré la GUI de dependencias que me muestra que de SayHellohecho está allí.

Nuestra empresa usa 4.6.1, también encontré este artículo que me llevó a PInvokeStackImbalance, pero eso no hace nada en mi caso.

Cualquier ayuda será muy apreciada.
Podría crear un repositorio temporal de GitHub si fuera necesario.

Respuestas

LukeTO'Brien Jan 22 2021 at 19:50

Ahora que sé que es un problema de cadenas, busqué un poco y encontré esta pregunta SO .
Así que al final utilicé el BSTRenfoque.

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

... Sin embargo, todavía no sé cómo logré obtener los caracteres chinos.