Pregunta

He construido un archivo DLL de C ++ que me gustaría llamar desde el código C #. Soy capaz de llamar a una función, pero el otro lanza una excepción cuando el código C # intenta cargar el archivo DLL.

La cabecera tiene el siguiente aspecto:

extern "C" __declspec(dllexport) BOOL Install();
extern "C" __declspec(dllexport) BOOL PPPConnect();

Esto produce una DLL con mesa de exportaciones ligeramente confuso (¿qué significa = foo foo en el campo de nombre?):

File Type: DLL

Section contains the following exports for PPPManager.dll

00000000 characteristics
499F44F0 time date stamp Fri Feb 20 16:04:00 2009
    0.00 version
       1 ordinal base
       2 number of functions
       2 number of names

ordinal hint RVA      name

      1    0 000078E4 Install = Install
      2    1 000079DC PPPConnect = PPPConnect

Mi P / Invoke declaraciones este aspecto:

[DllImport("PPPManager.dll")]
private static extern bool Install();

[DllImport("PPPManager.dll")]
private static extern bool PPPConnect();

La llamada a instalar rendimientos sin excepción, pero cuando llamo PPPConnect, aparece un MissingMethodException - "No se puede encontrar un punto de entrada 'PPPConnect' en un DLL PInvoke 'PPPManager.dll'"

He intentado quitar la extern y directivas declspec de la declaración de la función de instalación, de manera que PPPConnect es la única función exportada, y esto todavía no me deja llamar PPPConnect.

También he intentado hacer el DllImport por ordinal; esto da el mismo resultado que llama por su nombre -. Instalar los rendimientos, pero PPPConnect produce la excepción "No se puede encontrar un punto de entrada '# 2' ..."

El registro de interoperabilidad da:

[pinvokeimpl][preservesig]
bool  invivodata.Common.System.IPAQUtils::Install();
BOOLEAN (I1_WINBOOL_VAL) Install();

JIT ERROR FOR PINVOKE METHOD (Managed -> Native): 
[pinvokeimpl][preservesig]
bool  invivodata.Common.System.IPAQUtils::PPPConnect();
BOOLEAN (I1_WINBOOL_VAL) PPPConnect();

Esto es bien fuera de mi área de especialización, por lo que cualquier sugerencia o pensamientos sería bienvenido.

Gracias, Paul

editar: Resulta que este código hace el trabajo; el problema estaba en la última DLL no se propague al dispositivo. D'oh!

¿Fue útil?

Solución

¿Está utilizando un archivo .def en su proyecto DLL para exportar esas funciones? Si es así, retire y vuelva a intentarlo. Esta es sólo una suposición, porque parece que sus exportaciones no son lo que deberían ser, cuando usted hace una extern "C" (declspec dllexports).

He intentado esto con un simple DLL C ++ utilizando

extern "C" __declspec(dllexport) BOOL Install();
extern "C" __declspec(dllexport) BOOL PPPConnect();

y una sencilla aplicación de C # usando sus declaraciones PInvoke y ha funcionado bien.

Cuando hice un dumpbin / exportaciones en el DLL que vi:

Volcado de archivo PPPManager.dll

Tipo de Archivo: DLL

Sección contiene las siguientes exportaciones para PPPManager.dll

00000000 characteristics
499F6C2D time date stamp Fri Feb 20 20:51:25 2009
    0.00 version
       1 ordinal base
       2 number of functions
       2 number of names

ordinal hint RVA      name

      1    0 000110CD Install = @ILT+200(_Install)
      2    1 00011069 PPPConnect = @ILT+100(_PPPConnect)

Tenga en cuenta que los nombres exportados son diferentes en mi caso.

Otros consejos

Podría ser algo tan simple como PPPConnect no de una manera que consiga mal interpretado por el sistema operativo. Tratar implementar tanto Install y PPPConnect como no-ops (sólo tienen que regresen TRUE sin hacer nada más) y ver si el error persiste. Si es así, intentar cambiar el orden en el que se exportan (aún y cuando no-ops) y ver si el problema está ligado a ordenar (poco probable) o para otra cosa.

También puede utilizar la herramienta gráfica depends para confirmar lo mesa de las exportaciones de la DLL se parece, pero dudo que el problema viene de aquellos lugares.

De acuerdo a su descripción Instalar y PPPConnect difiere sólo en los nombres. Creo que sólo tiene que utilizar la versión .dll de edad con su aplicación en C #. A uno sin PPPConnect definido.

Las declaraciones se ve bien (por lo que yo puedo juzgar sin fuentes).

Muy buena información, pero como usted menciona, todo está en orden aquí. Pruebe a instalar las herramientas de depuración para Windows y ejecutando:

kd -z \path\to\PPPManager.dll -y \path\to\PPPManager.pdb -c "x pppmodule!*"

para obtener un mejor vaciado de la tabla de símbolos; se trata de un golpe ciego también, pero también se podría tratar:

extern "C" 
{
    __declspec(dllexport) BOOL Install();
    __declspec(dllexport) BOOL PPPConnect();
};

En el caso de la declspec está haciendo algo raro.

utilizar Dependency Walker y abrir el archivo DLL para verificar qué servicios están disponibles métodos

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top