P / Invoke et .NET Target Framework [dupliquer]

Jan 22 2021

Ce problème me fait monter le mur ... Je dis juste.

Mon entreprise possède une ancienne bibliothèque C ++ et j'ai été chargé de créer un wrapper .NET.
Je n'ai aucune expérience de C ++ ou P / Invoke donc pour commencer j'essaye une méthode simple.

J'ai lu la documentation officielle et j'ai également trouvé un joli tutoriel .
Cependant, j'ai découvert que le framework .NET cible de l'application consommatrice fait une différence.
Le code P / Invoke du didacticiel fonctionne bien, mais j'ai remarqué qu'il cible le profil client .NET Framework 4 .
Si je place des points d'arrêt, ils sont touchés et tout fonctionne comme prévu, si je cible un cadre supérieur à 4, le programme se bloque sans exception.

J'ai une méthode vraiment simple définie 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();

(J'ai essayé de définir CallingConvention et CharSet sur l'attribut dans différentes combinaisons, j'ai réussi à obtenir des caractères chinois, mais rien ne fonctionne plus haut que Framework 4)

Mon projet C ++ a API=__declspec(dllexport)défini les définitions de préprocesseur et la convention d'appel est _stdcall (\Gz)(j'ai également essayé _cdecl).
Le projet C # fonctionne bien sur Framework 4 , lorsque je passe à quelque chose au-dessus de cela, il se termine sans exception.
J'ai également trouvé l' interface graphique des dépendances qui me montre que SayHelloc'est bien là.

Notre société utilise la version 4.6.1, je suis également tombé sur cet article qui m'amène à PInvokeStackImbalance mais cela ne fait rien dans mon cas.

Toute aide serait grandement appréciée.
Je pourrais créer un dépôt temporaire GitHub si nécessaire.

Réponses

LukeTO'Brien Jan 22 2021 at 19:50

Maintenant que je sais que c'est un problème de chaîne, j'ai fait une petite recherche et j'ai trouvé cette question SO .
Donc, à la fin, j'ai utilisé l' BSTRapproche.

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

... Je ne sais toujours pas comment j'ai réussi à obtenir des caractères chinois.