P / Invoke e .NET Target Framework [duplicado]

Jan 22 2021

Este problema está me deixando maluco ... Só estou dizendo.

Minha empresa tem uma biblioteca C ++ legada e recebi a tarefa de criar um wrapper .NET.
Não tenho experiência em C ++ ou P / Invoke, então, para começar, estou tentando um método simples.

Eu li a documentação oficial e também encontrei um bom tutorial .
No entanto, descobri que a estrutura .NET de destino do aplicativo de consumo faz a diferença.
O código P / Invoke do tutorial funciona bem, mas percebi que ele tem como alvo o .NET Framework 4 Client Profile .
Se eu colocar pontos de interrupção, eles serão atingidos e tudo funcionará conforme o esperado; se eu visar um framework maior que 4, o programa falha sem exceção.

Eu tenho um método muito simples definido em C ++:
framework.h

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

dllmain.cpp

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

C#

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

(Eu tentei definir CallingConvention e CharSet no atributo em diferentes combinações, consegui obter caracteres chineses, mas nada funcionando além do Framework 4)

Meu projeto C ++ tem API=__declspec(dllexport)Definições de pré-processador definidas e convenção de chamada _stdcall (\Gz)(eu também tentei _cdecl).
O projeto C # funciona bem no Framework 4 , quando eu mudo para qualquer coisa acima disso, ele simplesmente sai sem exceção.
Eu também encontrei Dependências GUI que está me mostrando que SayHellorealmente existe.

Nossa empresa usa 4.6.1, também encontrei este artigo que me levou a PInvokeStackImbalance, mas isso não faz nada no meu caso.

Qualquer ajuda seria muito apreciada.
Eu poderia criar um repositório temporário do GitHub, se necessário.

Respostas

LukeTO'Brien Jan 22 2021 at 19:50

Agora que sei que é um problema de string, fiz uma pequena pesquisa e encontrei esta pergunta SO .
Então, no final, usei a BSTRabordagem.

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

... Ainda não sei como consegui os caracteres chineses.