2010-11-03 20 views
7

Tengo una biblioteca estática. Esta biblioteca han definido la siguiente funciónPrefijo L para cadenas en C++

int WriteData(LPTSTR s) 

La muestra a llamar a la función es

LPTSTR s = (LPTSTR) L"Test Data"; 
int n = WriteData(s); 

WriteData devuelven 0 en caso de éxito y -1 en caso de error.

Estoy escribiendo una DLL dinámica para exportar esta función.

int TestFun(LPTSTR lpData) 
{ 
    return WriteData(lpData); 
} 

A C++ resultado aplicación de prueba

LPTSTR s = (LPTSTR) L"Test Data"; 
TestFun(s); //OK return 0 

LPTSTR s = (LPTSTR) "Test Data";  
TestFun(s); //Fail return -1 

tengo que llamarlo desde una aplicación C#. Asumo mi firma DLL-Import sería:

 [DllImport("Test.dll")] 
     private static extern int TestFun(String s); 

Mi pregunta es muy simple ¿Cómo puedo llamarlo desde .Net? Como se puede ver que tengo control sobre

TestFun(LPTSTR lpData) 

pero ningún control sobre

WriteData(LPTSTR s) 

Gracias a todos por sus aportaciones. Hasta ahora estoy atascado en el casting. Creo que mi problema se resolverá cuando pueda tomar la información del usuario y escribir 2 líneas para el casting en lugar de la línea siguiente.

LPTSTR s = (LPTSTR) L"Test Data"); //<= How can ii take input from user and 
    TestFun(s); //OK return 0 
+5

El uso de TCHAR tuvo sentido hace 10 años. No más, no hay un sistema operativo que no sea Unicode que deba soportar. Haz todo wchar_t y sigue adelante. –

+0

¿Cómo puedo hacer eso? – Manjoor

+0

¿Qué 'no funciona' cuando pasa lpData a la función WriteData? – harper

Respuesta

7

El prefijo L hace que la cadena sea una cadena wchar_t. Puede usar la función de API de Windows MultiByteToWideChar para convertir una cadena ANSI en una cadena wchar_t.

+0

No funciona en mi caso – Manjoor

+1

¿Cómo no funciona? –

+6

@Manjoor: Realmente deberías explicar POR QUÉ no está funcionando. Estos tipos están tratando de ayudarlo sin costo para usted y sin ningún beneficio para ellos, y usted está desestimando sus esfuerzos y haciéndoles sentir que están perdiendo el tiempo porque usted es demasiado perezoso para decirles exactamente por qué su solución no lo hace. no funciona para usted –

0

Me gustaría envolver sus cadenas en la macro _T(...). De esta forma es portátil entre las compilaciones ANSI y UNICODE.

Tenga en cuenta que está utilizando el tipo de cadena portátil - LPTSTR - tenga en cuenta el T. Cambiará entre ANSI y UNICODE en función de la configuración de compilación.

+0

Nota: la macro '_T' es específica de Microsoft, no genérica de C++, como LPTSTR. No es que sea difícil de reimplantar. –

6

La "función" específica para realizar el prefijo L es una macro TEXT() o _T(). (TEXTO está definido por el SDK de Windows, _T es una extensión del Microsoft C Runtime).

Estas funciones agregan automáticamente el prefijo L cuando su proyecto está construido con soporte Unicode (que es el predeterminado para nuevos proyectos ahora en la mayoría de los entornos MS Dev) o lo dejan para proyectos no unicode (o ansi) configurados.

No hacer este reparto:

LPTSTR s = (LPTSTR) L"ABC"; // Working fine 
    WriteData(s); 

Si el proyecto nunca fue configurado para no Unicode, entonces L "ABC" seguiría siendo un conjunto de caracteres anchos, pero LPTSTR se convertiría en un puntero a una matriz de caracteres de 8 bits.

Así es como asignar correctamente una cadena a una cadena Ansi, Unicode o "Texto".(El texto puede ser Ansi o Unicode dependiendo de la configuración del proyecto) (Dejé la L porque es redundante, y agregué una C, porque los literales de la cadena deberían ser constantes).

PCSTR p1 = "ABC"; 
PCWSTR p2 = L"ABC"; 
PCTSTR p3 = TEXT("ABC"); 
+0

Gracias por su respuesta, pero no resuelve mi problema. – Manjoor

+5

¿Qué tal si le dices lo que no funciona en lugar de ponerle la carga a él para que adivine? Se toma el tiempo de su día para responder a su pregunta sin ningún costo para usted. Al menos podrías darle alguna información. –

1

Pienso que usted es confuso, ya que su función debería funcionar bien:

int TestFun(LPTSTR lpData) 
{ 
    return WriteData(lpData); // Should be happy 
} 

Pero cuando llamada su función, tendrá que tener cuidado:

TestFun((LPTSTR) L"ABC"); // Will work fine 
TestFun((LPTSTR) "ABC"); // Will not work 

Esto se debe a que "ABC" y "ABC" son dos cosas diferentes. Si nos fijamos en ellos en la memoria:

"ABC" | 65 66 67 00 
L"ABC" | 65 00 66 00 67 00 00 00 

Editado para añadir:

hay nada como prefijo L de .Net

Esto es simplemente incorrecto. Acabo de abrir "Nuevo Proyecto-> C++ -> CLR Console" en VisualStudio, y la primera línea es:

Console::WriteLine(L"Hello World"); 
+0

Como mencioné en mi pregunta, esto va a ser dinámico dll. Este dll se llamaría desde una aplicación .Net. No hay nada como el prefijo L en .Net – Manjoor

+0

La función de exportación dll 'TestFun'. ¿Me puede dar una idea de cómo puedo llamarlo desde una aplicación C#? Esto es dll-import [DllImport ("Prueba.dll ")] private static extern int TestFun (String s); – Manjoor

+0

Gracias por el esfuerzo, pero lo estoy llamando desde C# para probar y necesita ser llamado desde easylanguage para que no pueda usar L. – Manjoor

1

Probar:

[DllImport("Test.dll")] 
private static extern int TestFun([MarshalAs(UnmanagedType.LPTStr)] string s); 

Más información sobre el cálculo de referencias con el MarshalAsAttribute en MSDN.

Cuestiones relacionadas