2009-02-03 4 views
7

Compte tenu de cette déclaration de l'API C, comment serait-il importé en C#?Comment faire pour importer const char * API en C#?

const char* _stdcall z4LLkGetKeySTD(void); 

Je suis en mesure d'obtenir jusqu'ici:

[DllImport("zip4_w32.dll", 
     CallingConvention = CallingConvention.StdCall, 
     EntryPoint = "z4LLkGetKeySTD", 
     ExactSpelling = false)] 
    private extern static const char* z4LLkGetKeySTD(); 

Répondre

12

Essayez cette

[DllImport("zip4_w32.dll", 
     CallingConvention = CallingConvention.StdCall, 
     EntryPoint = "z4LLkGetKeySTD", 
     ExactSpelling = false)] 
    private extern static IntPtr z4LLkGetKeySTD(); 

Vous pouvez ensuite convertir le résultat d'une chaîne à l'aide Marshal.PtrToStringAnsi(). Vous devrez toujours libérer la mémoire pour l'IntPtr en utilisant la méthode Marshal.Free * appropriée.

+0

Comment savez-vous quelle méthode Marshal.Free * devrait être utilisée? –

+0

@thelaughingdm, cela dépend de la façon dont la mémoire a été allouée. Le Marshal.FreeCoTaskMemAlloc libère un CoTaskMemAlloc natif. Chacun travaille avec une méthode native particulière – JaredPar

2

utiliser juste 'string' au lieu de 'const char *. Editer: Ceci est dangereux pour la raison expliquée par JaredPar. Si vous ne voulez pas un gratuit, n'utilisez pas cette méthode.

+0

Vous avez pris les mots sur ma bouche! – leppie

+0

Ne pas utiliser de chaîne. Si le retour d'une fonction est une chaîne, le CLR tentera de CoTaskMemFree le pointeur natif qui n'est probablement pas ce que l'utilisateur veut ici – JaredPar

+1

http://msdn.microsoft.com/en-us/magazine/cc164193.aspx bottom of the Paragrah sous la figure 8 – JaredPar

4

Toujours utiliser C++ const char * ou char * et non std :: string.

Gardez également à l'esprit que char dans C++ est un sbyte dans C# et char non signé est un octet dans C#.

Il est conseillé d'utiliser un code non sécurisé lors de l'utilisation de DllImport.

[DllImport("zip4_w32.dll", 
    CallingConvention = CallingConvention.StdCall, 
    EntryPoint = "z4LLkGetKeySTD", 
    ExactSpelling = false)] 
private extern static sbyte* or byte* z4LLkGetKeySTD(); 

void foo() 
{ 
    string res = new string(z4LLkGetKeySTD()); 
}