2010-11-19 10 views
5

Mi programa .Net utiliza un Fortran Dll para realizar una función matemática (Arpack, resuelve modos propios). Creo que el Fortran contiene variables estáticas y generalmente no es seguro para subprocesos. También es muy complicado y probablemente requerirá mucho trabajo para hacerlo seguro. El Dll no es muy grande (700K) así que solo quiero cargarlo muchas veces (digamos 4 o 8) para permitir que los hilos funcionen al mismo tiempo. ¿Alguien tiene alguna idea de cómo puedo hacer esto? Escuché que LoadLibrary siempre devolverá el mismo identificador cuando se lo llame varias veces. Por lo tanto, tal como está, mi única solución es tener varias copias de mi Dll en el disco (Arpack1.dll, Arpack2.dll, etc.) y cargarlas según sea necesario. Bastante horribleCargue Dll varias veces para permitir multihebras en .Net

¿Alguna idea?

Euan

+0

¿El código de Fortran es administrado o no administrado? – CodesInChaos

+0

¿Hay algo así como Fortran gestionado? Si es así, me encantaría usarlo. –

+0

Puedes obtener Fortran.Neto, pero el último que miré fue un poco caro. Creo que es F77 o algo horrible – Euan

Respuesta

2

La solución alternativa que ha encontrado es en realidad una bastante decente. Puede haber pequeñas probabilidades de que LoadLibraryEx() con la opción LOAD_LIBRARY_AS_IMAGE_RESOURCE funcione. Esa opción te permite cargarlo varias veces. Aunque lo dudo seriamente, la DLL casi con certeza depende de que su código de soporte de tiempo de ejecución se inicialice a través de DllMain.

Una cosa que no escuché mencionar es el dolor de tener que usar GetProcAddress(). Asegúrate de hacerlo o seguirás pisoteando las variables globales cuando comiences a enhebrar. Cada hilo debe usar su propia dirección.

+0

de acuerdo. Tiene que ser mejor que pescar con el viejo código Fortran ... – Euan

2

Cargando el archivo DLL no es la manera de crear un hilo. Sus dos opciones son usar AppDomains o procesos separados por completo.

La manera más fácil de hacerlo podría ser simplemente usar una disposición maestro/esclavo, donde la lógica que utiliza la biblioteca se hace en el proceso esclavo. El maestro inicia tantos "esclavos" como quiera o necesite, y luego recoge los valores devueltos.

Escriba el código en el "esclavo" como si fuera de una sola hebra, porque ... lo es.

Use System.Diagnostics.Process.Start desde el maestro, para iniciar estas cosas.


En general, la copia de la DLL y cargar todas las copias no es un enfoque a prueba de fallos; los archivos DLL pueden acceder a recursos del sistema operativo como mutexes o incluso archivos de bloqueo. Estos no sabrán que se supone que las copias están "separadas".

Si su biblioteca es puramente una biblioteca de cálculo y REALMENTE REALMENTE desea hacer el enfoque de copiar y cargar las copias, puede crear enlaces duros para evitar tener que duplicar el archivo DLL real. (fsutil hardlink create en Win7 o Vista)

+0

¿Estás seguro de que es posible usar AppDomains? Acabo de probarlo, pero no pareció funcionar. Básicamente utilicé este ejemplo y lo modifiqué un poco para llamar a un método en la biblioteca: http://msdn.microsoft.com/en-us/library/3c4f1xde(v=vs.110).aspx – Karsten

0

Al salir, no puede cargar la biblioteca varias veces. supongo que hay dos posibilidades:

En ambas soluciones es necesario considerar un método de intercambio de datos entre los procesos/dominios de la aplicación. De todos modos, ¡no será una tarea simple!

+0

Hola, gracias por el responder. Parece que ambas soluciones son más complejas que simplemente copiar el Dll. No es ese el caso? – Euan

+0

Sí, eso será más complejo La pregunta aquí es, ¿quieres hacerlo bien o debería funcionar por el momento? Lo más probable es que te muevas con la copia, pero en un momento te morderá. –

Cuestiones relacionadas