Título: importar dll de c++ en c#
Publicado por: ^kazike^ en 9 Septiembre 2009, 18:03 pm
Hola a todos: estoy haciendo una aplicacion en c# donde quiero importar una dll ya creada en c++ pero al ejecutarla me da el error: No se puede encontrar el punto de entrada denominado 'suma' en el archivo DLL 'DLL_lib.dll'. el codigo de la dll es el siguiente: .h #ifdef DLL_LIB_EXPORTS #define DLL_LIB_API __declspec(dllexport) #else #define DLL_LIB_API __declspec(dllimport) #endif
// Clase exportada de DLL_lib.dll class DLL_LIB_API CDLL_lib { private: int a; int b; public: CDLL_lib(void); // TODO: agregar métodos aquí. double multiplica(); int getA(); int getB(); void setA(int a); void setB(int b); };
DLL_LIB_API int suma(void);
extern DLL_LIB_API int nDLL_lib;
DLL_LIB_API int fnDLL_lib(void);
.cpp #include "stdafx.h" #include "DLL_lib.h"
#ifdef _MANAGED #pragma managed(push, off) #endif
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; }
#ifdef _MANAGED #pragma managed(pop) #endif
// Ejemplo de variable exportada DLL_LIB_API int nDLL_lib=0;
// Ejemplo de función exportada. DLL_LIB_API int fnDLL_lib(void) { return 42; }
DLL_LIB_API int suma(void) { return 5+5; }
// Constructor de clase exportada. // Consultar DLL_lib.h para definir la clase CDLL_lib::CDLL_lib() { this->a = 0; this->b = 0; }
int CDLL_lib::getA() { return a; }
int CDLL_lib::getB() { return b; }
void CDLL_lib::setA(int a) { this->a = a; }
void CDLL_lib::setB(int b) { this->b = b; }
double CDLL_lib::multiplica() { return (double)a*b; }
y el archivo .cs using System; using System.Collections.Generic; using System.Windows.Forms; using System.Runtime.InteropServices;
namespace app_usa_dll { class Program { /// <summary> /// Punto de entrada principal para la aplicación. /// </summary> [STAThread] [DllImport(/*" ..\\..\\..\\debug\\*/"DLL_lib.dll")] public static extern int suma(); [DllImport(/*" ..\\..\\..\\debug\\*/"DLL_lib.dll")] public static extern void setA(int a); [DllImport(/*" ..\\..\\..\\debug\\*/"DLL_lib.dll")] public static extern void setB(int b); [DllImport(/*" ..\\..\\..\\debug\\*/"DLL_lib.dll")] public static extern double multiplica(); [DllImport(/*" ..\\..\\..\\debug\\*/"DLL_lib.dll")] public static extern int getA(); [DllImport(/*" ..\\..\\..\\debug\\*/"DLL_lib.dll")] public static extern int getB(); static void Main() { int a = 0; int b = 0; double c = 0; int res = 0; Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); //funciones de la dll try { /*a = setA(int.Parse(textBox3.Text)); b = setB(int.Parse(textBox2.Text)); c = multiplica();*/ res = suma(); setA(int.Parse("5")); a = getA(); setB(int.Parse("6")); b = getB(); c = multiplica(); res = suma(); } catch (DllNotFoundException exc) { Console.WriteLine(exc.ToString()); } catch (EntryPointNotFoundException exc) { Console.WriteLine(exc.ToString()); } Application.Run(new Form1(a, b, c, res)); } } }
Alguna idea?¿ Gracias a todos
Título: Re: importar dll de c++ en c#
Publicado por: MazarD en 9 Septiembre 2009, 18:19 pm
Te falta el .def Sería algo como: DLL_lib.def LIBRARY DLL_lib EXPORTS CDLL_lib getA getB etc
[/pre] Por lo demás parece todo correcto, saludos!
Título: Re: importar dll de c++ en c#
Publicado por: ^kazike^ en 9 Septiembre 2009, 18:59 pm
mmm he probado a hacer lo dices, MazarD y me tira: error LNK2001: símbolo externo CDLL_lib sin resolver d:\Documents and Settings\Ruben\Visual Studio 2005\Projects\DLL_CS\DLL_lib\DLL_lib.def
en la linea 1 archivo .def LIBRARY DLL_lib EXPORTS CDLL_lib getA getB setA setB multiplica suma
:-[
Título: Re: importar dll de c++ en c#
Publicado por: MazarD en 9 Septiembre 2009, 21:01 pm
Creo que no puedes exportar el constructor, no estoy seguro ya que nunca he tenido la necesidad. Porqué no pones el contenido del constructor en el DllMain process_attach que es el punto en el que se supone debes realizar las tareas de inicialización? O creas una función privada que haga lo mismo que el constructor y lo llamas desde process_attach. O creas una función pública exportada pero que no sea constructor, que se llame Init y te aseguras de que deba ser llamada desde el programa que cargue la dll.
Si te paras a pensar no tiene mucho sentido tener constructor en una dll ya que no vas a poder de forma directa instanciar un objeto que vaya a llamarlo.
Saludos!
Título: Re: importar dll de c++ en c#
Publicado por: ^kazike^ en 10 Septiembre 2009, 09:13 am
Ya elimine el constructor de la declaracion y compila sin problemas, pero sigue dando el error de que no encuentra el punto de entrada.... :-\ el archivo .def tengo que hacer algo mas cn el?algun include o algo asi o solo con crearlo basta?? Saludos
Título: Re: importar dll de c++ en c#
Publicado por: MazarD en 10 Septiembre 2009, 13:06 pm
Ya un poco extrañado he decidido probarlo y a mi me funciona bien, la única diferencia con tu código es que todos mis archivos se llaman 'prova' y el nombre de la clase también claro. Entonces una vez corriendo tendrás el problema de que setA y setB no te funcionarán puesto que utiliza this cuando en realidad no es una instancia del objeto, esto es porque desde c# declaras (estas obligado) la función como static cuando en realidad necesariamente debe ser miembro del objeto para poder acceder al valor de las variables para la instancia (this->a o this->b). Probablemente este es el porque no se ven dlls con clases, no tiene mucho sentido si no vas a poder instanciar la clase desde el lenguaje que la utiliza. Yo creo que tienes dos opciones, declarar static a y b o directamente pasar de la clases y hacerlo Cstyle x) Te dejo tu código con las modificaciones que he hecho para que funcione. Saludos! prova.def: LIBRARY prova EXPORTS getA getB setA setB multiplica suma nDLL_lib fnDLL_lib
#define DLL_LIB_EXPORTS #ifdef DLL_LIB_EXPORTS #define DLL_LIB_API __declspec(dllexport) #else #define DLL_LIB_API __declspec(dllimport) #endif DLL_LIB_API double multiplica(); DLL_LIB_API int getA(); DLL_LIB_API int getB(); DLL_LIB_API void setA(int a); DLL_LIB_API void setB(int b); DLL_LIB_API int suma(void); DLL_LIB_API int nDLL_lib=0; DLL_LIB_API int fnDLL_lib(void);
#include "stdafx.h" #include "prova.h" int a; int b; #ifdef _MANAGED #pragma managed(push, off) #endif BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: a=0; b=0; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } #ifdef _MANAGED #pragma managed(pop) #endif // Ejemplo de función exportada. DLL_LIB_API int fnDLL_lib(void) { return 42; } int suma(void) { return 5+5; } int getA() { return a; } int getB() { return b; } void setA(int pa) { a = pa; } void setB(int pb) { b = pb; } double multiplica() { return (double)a*b; }
WindowsApplication1 c# [STAThread] [DllImport("C:\\Documents and Settings\\lab\\Escritorio\\dispatch\\prova\\debug\\prova.dll")] public static extern int suma(); [DllImport("C:\\Documents and Settings\\lab\\Escritorio\\dispatch\\prova\\debug\\prova.dll")] public static extern void setA(int a); [DllImport("C:\\Documents and Settings\\lab\\Escritorio\\dispatch\\prova\\debug\\prova.dll")] public static extern void setB(int b); [DllImport("C:\\Documents and Settings\\lab\\Escritorio\\dispatch\\prova\\debug\\prova.dll")] public static extern double multiplica(); [DllImport("C:\\Documents and Settings\\lab\\Escritorio\\dispatch\\prova\\debug\\prova.dll")] public static extern int getA(); [DllImport("C:\\Documents and Settings\\lab\\Escritorio\\dispatch\\prova\\debug\\prova.dll")] public static extern int getB(); private void button1_Click(object sender, EventArgs e) { MessageBox.Show(suma().ToString()); setA(11); setB(11); MessageBox.Show(multiplica().ToString()); MessageBox.Show(getA().ToString()); MessageBox.Show(getB().ToString()); }
Título: Re: importar dll de c++ en c#
Publicado por: ^kazike^ en 10 Septiembre 2009, 13:37 pm
perfecto. muchas gracias xla ayuda!! :D
|