2013-05-08 18 views
5

Ho guardato in giro per googleverse e stack overflow e ho visto diverse domande simili a questo ma nessuna delle risposte che ho trovato ha funzionato per me. Sono un nuovo membro quindi non posso commentare le risposte nella domanda di qualcun altro per chiedere chiarimenti, quindi ho dovuto ricorrere al mio.passare una serie di stringhe da C# a una dll C++ e viceversa

Ok, quindi sto provando a passare un array di stringhe da un'applicazione C# a una DLL C++ e quindi a prendere quelle informazioni in un'altra applicazione C#. Credo che sto passando a C++ correttamente ma non riesco a ottenere le stringhe corrette dalla DLL.

sto passando per C++ in questo modo:

[DllImport("KinectPlugins.dll", CallingConvention = CallingConvention.Cdecl)] 
    private static extern void SetGrammarData(string[] strArr, int size); 


    public void SetGrammar(string[] strArr) 
    { 
     SetGrammarData(strArr, strArr.Length); 
    } 

mio codice C++ è simile al seguente:

#define EXPORT_API __declspec(dllexport) 
#pragma data_seg(".SHARED") 
    char** grammarData; 
    int grammarDataLength = 0; 
#pragma data_seg() 
#pragma comment(linker, "/section:.SHARED,RWS") 

EXPORT_API void SetGrammarData(char** strArr, int size) 
{ 
    grammarData = strArr; 
    grammarDataLength = size; 
} 

EXPORT_API int GetGrammarDataLength() 
{ 
    return grammarDataLength; 
} 
EXPORT_API char** GetGrammarData() 
{ 
    return grammarData; 
} 

Il mio codice per poi afferrare le informazioni nel mio altre applicazioni C# è simile al seguente:

In teoria questo dovrebbe funzionare in base alla mia ricerca, come ho visto molte altre persone usano lo stesso codice In pratica, ciò che accade è che passo in:

SetGrammar(new string[] { "b", "a" }); 

e ciò che ritorna l'altro lato è:

stringArray[0] = 
stringArray[1] = H-▬l☺ 

Nel caso alcuni non può vederlo per qualche motivo o un altro StringArray [1 ] è uguale a H, -, una linea spessa, una simbolo di faccia felice. Questo ovviamente non è quello che ho inserito.

Qualcuno ha un'idea di dove potrei sbagliare con questo? Ho sbattuto la testa contro questo problema da un po 'di tempo e potrei davvero usare un po' di aiuto in quanto mi sembra che manchi qualcosa di molto semplice qui.

Edit: come da suggerimento di antijon ho cambiato il mio SetGrammarData di fare una copia delle corde, ma sto ancora funzionando in un problema.

nuovo codice:

(inside the data_seg) 
wchar_t* grammarData; 
(end data_seg) 

EXPORT_API void SetGrammarData(wchar_t* strArr, int size) 
{ 
    delete[] grammarData; 
    grammarData = new wchar_t[size]; 
    std::memcpy(grammarData, strArr, sizeof(wchar_t) * size); 
    grammarDataLength = size; 
} 
EXPORT_API wchar_t* GetGrammarData() 
{ 
    return grammarData; 
} 

Ora io alla fine con questa uscita:

stringArray[0] = 8 
stringArray[1] = 

Il codice C# è rimasta la stessa. C'è qualcos'altro che devo cambiare che mi manca?

Edit2: appena realizzato che wchar_t è come un char, non è una stringa, non so perché ho pensato che si comportava come una stringa. Tornando al tavolo da disegno, è necessario capire come copiare al meglio un wchar_t **. Non che abbia esperienza con il C++, ma non credo sia possibile ottenere la lunghezza di un wchar_t * senza passarlo in me stesso, ma dovrò esaminarlo.

Edit3: Finalmente ha funzionato correttamente.

Ecco quello che ho finito con:

(inside the data_seg) 
std::wstring* grammarData; 
(end data_seg) 

EXPORT_API void SetGrammarData(wchar_t** strArr, int size) 
{ 
    delete[] grammarData; 
    grammarDataLength = size; 
    grammarData = new std::wstring[size]; 
    for(int i = 0; i < size; i++) 
    { 
     grammarData[i] = std::wstring(strArr[i]); 
    } 
} 

EXPORT_API const wchar_t** GetGrammarData() 
{ 
    const wchar_t** wct = new const wchar_t*[grammarDataLength]; 
    for(int i = 0;i<grammarDataLength;i++) 
    { 
     const wchar_t* t = grammarData[i].c_str(); 
     wct[i] = t; 
    } 
    return wct; 
} 

Edit4: pensato che avevo funziona correttamente, non era corretta. Stavo testando con un exe che ritorna a se stesso ma quando passava attraverso la dll in un altro exe nulla sarebbe passato. Ora ho funzionare:

(inside the data_seg) 
wchar_t grammarData[32][50] = {}; 
(end data_seg) 

EXPORT_API void SetGrammarData(wchar_t** strArr, int size) 
{ 
    grammarDataLength = size; 
    for(int i = 0; i < size; i++) 
    { 
     wcscpy(grammarData[i], strArr[i]); 
    } 
    grammarDataChanged = 1; 
} 

EXPORT_API wchar_t** GetGrammarData() 
{ 
    wchar_t** wct = new wchar_t*[grammarDataLength]; 
    for(int i = 0;i<grammarDataLength;i++) 
    { 
     wct[i] = grammarData[i]; 
    } 

    grammarDataChanged = 0; 
    return wct; 
} 
+0

hai provato a passare l'array come parametro 'ref'? –

+0

vedere questo: http://stackoverflow.com/questions/2372061/c-sharp-struct-no-parameterless-constructor-see-what-i-need-to-accomplish e http://stackoverflow.com/questions/ 2345945/memoria tentata-per-leggere o protetta da scrittura-questa-è-spesso-un'indicazione-che-o e http://stackoverflow.com/questions/2344929/pointers-in-c-sharp- to-retrieve-reference-from-dllimport-function –

+0

e http://stackoverflow.com/questions/2343272/dllimport-unmanaged-non-net-dll-to-net-project-representing-char-and-void –

risposta

3

paio di possibili problemi qui:

  1. Per impostazione predefinita, .NET sarà maresciallo come wchar_t, non char. Sarà necessario contrassegnare i parametri della stringa di input/output con MarshalAsAttribute per utilizzare char.
  2. Se si desidera mantenere le stringhe, sarà necessario crearne una copia all'interno della funzione C. I puntatori dati nella chiamata di funzione a SetGrammarData non sono garantiti per persistere.
+0

Hmm, non avevo nemmeno preso in considerazione il n. 2. Immagino che vada a dimostrare che ho lavorato su questo problema per troppo tempo e ho avuto troppe iterazioni per aver dimenticato qualcosa del genere. Proverò a risolverlo perché probabilmente è corretto, visto che è il mio problema principale. Oggi potrei non averlo testato, visto che devo partire molto presto. Potrebbe essere necessario attendere domani per accettare questa risposta. – Adam

+0

hmm, ho provato: EXPORT_API void SetGrammarData (wchar_t * strArr, int size) { delete [] grammarData; grammarData = new wchar_t [size]; std :: memcpy (grammarData, strArr, sizeof (wchar_t) * size); grammarDataLength = dimensione; } EXPORT_API wchar_t * GetGrammarData() { return grammarData; } ma ora tutto quello che ottiene indietro è: StringArray [0] = 8 StringArray [1] = C'è qualcos'altro che sto facendo male che siete a conoscenza? – Adam

Problemi correlati