2009-11-10 8 views
1

J'ai un C non géré ++ dll qui exporte les méthodes suivantes:Sending Byte [] [] inbetween C++ dll non géré et C# géré dll

ERASURE_API void encode(unsigned char ** inp, unsigned char ** outp, 
    unsigned int *block_nums, size_t num_block_nums, size_t sz); 

ERASURE_API void decode(unsigned char ** inp, unsigned char ** outp, 
    unsigned int * index, size_t sz); 

Taille de InP et SORT peut être aussi grand que 10Ko, Que serait être le meilleur moyen d'appeler ces méthodes à partir du code managé C#?

EDIT: J'ai fait l'implémentation suivante, et cela fonctionne, mais c'est le moyen le plus efficace de le faire.

C++:

ERASURE_API void encode_w(unsigned char * inpbuf,int k, unsigned char * outpbuf, 
    int nfecs, unsigned int * block_nums, size_t num_block_nums, size_t sz) 
{ 
    unsigned char ** inp= new unsigned char*[k]; 
    for(i=0;i<k;i++){ 
     inp[i] = inpbuf+i*sz; 
    } 

unsigned char ** outp= new unsigned char *[nfecs]; 
    for(i=0;i<nfecs;i++){ 
     outp[i] =outpbuf+i*sz; 
    } 
    encode(inp,outp,block_nums,num_block_nums,sz); 
    delete [] inp; 
    delete [] outp; 
} 

C#:

[DllImport("erasure.dll")] 
public static extern void encode_w([In] byte[] inpbuf,int k,[Out] byte[] outpbuf, 
    int nfecs, uint[] block_nums, int num_block_nums, int sz); 
+1

est-ce que le point d'entrée et le point de sortie peuvent pointer sur le même réseau que dans un chevauchement? –

+0

Cela pourrait être une option. – rkatiyar

Répondre

2

est C++/CLI une option? OMI, c'est ce genre de scénarios de marshaling interop/custom complexes pour lequel il a été conçu.

+0

Combien d'inconvénients de performance nous parlons ici avec C++/CLI. J'ai besoin d'une implémentation rapide pour l'encodage et le décodage d'effacement, c'est pourquoi j'ai préféré choisir C++ non géré. – rkatiyar

+0

Désolé, je voulais dire: utilisez C++/CLI pour l'interopération entre natif/géré. L'inconvénient est: vous vous retrouvez avec 3 bases de code (1 C++ natif, 1 C++/CLI, 1 C#). – Brannon

+0

Bien sûr, si vous possédez la bibliothèque C++ native, vous pouvez personnaliser l'interface pour mieux prendre en charge P/Invoke. Si c'est le cas, décrivez votre scénario un peu plus afin que quelqu'un puisse donner une recommandation favorable à P/Invoke. – Brannon

-2

Je recommande de créer un wrapper COM pour ces fonctions.

+0

Je crois que c'est ce qu'il essaie de faire. Le problème est de ramener le char ** à C#. – ParmesanCodice

+0

Il peut représenter char ** comme une interface distincte et fournir des méthodes pratiques pour accéder aux données – Alex

+0

Je veux créer un wrapper COM en C++, pas en C#. Et que de l'utiliser en C# – Alex

1

Avez-vous des données entre au maréchal tas managé et natif? Si vous déplacez toutes les opérations sur le tampon vers votre DLL native, vous pouvez éviter le coût de la copie de données entre les tas. Cela signifie que vous devez allouer les données sur le tas natif, les renvoyer dans un paramètre IntPtr ref, puis conserver l'adresse du tampon dans IntPtr (équivalent .Net de void *) et le transmettre. Une fois que vous avez terminé avec le tampon, vous pouvez appeler une autre fonction dans votre DLL natif pour supprimer le tampon. Utilisez System.Runtime.InteropServices.Marshal.Copy lorsque vous devez copier les données dans le tas géré (c'est ce que le marshaller du CLR a appelé pour les types intégrés de marshalling).

La création d'enveloppes COM des fonctions d'exploitation de tampon serait un peu plus lente mais rendrait le code plus lisible. Toutefois, l'allocation sur le tas COM peut être un peu plus lente car le code managé peut également verrouiller le tas COM.

+0

Merci pour votre commentaire, je vais certainement essayer vos suggestions. Je suis très nouveau pour .NET et C#. Je ne savais pas IntPtr étaient équivalents à void *.Je pensais qu'ils ne tiendraient que des refs int :( – rkatiyar

Questions connexes