Bueno... Antes de leer tu respuesta probé con LoadLibrary y GetProcAddress y no me dio ningún error. La librería sí se carga pero cuando intento obtener la dirección de una función exportada me dice que no encuentra esa función en la librería. Lo probé con dos funciones exportadas que tengo en la librería y en las dos dice lo mismo. La primera función exportada la copié de la ayuda del C++ Builder.
Aquí está el código de la librería:
#include <windows.h>
double dblValue(double);
double halfValue(double);
extern "C" __declspec(dllexport) double changeValue(double, bool);
double dblValue(double value)
{
return value * value;
};
double halfValue(double value)
{
return value / 2.0;
}
double changeValue(double value, bool whichOp)
{
return whichOp ? dblValue(value) : halfValue(value);
}
#define EOF (-1)
#ifdef __cplusplus // If used by C++ code,
extern "C" { // we need to export the C interface
#endif
__declspec(dllexport) int myPuts(LPTSTR lpszMsg)
{
DWORD cchWritten;
HANDLE hStdout;
BOOL fRet;
// Get a handle to the standard output device.
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
if (INVALID_HANDLE_VALUE == hStdout)
return EOF;
// Write a null-terminated string to the standard output device.
while (*lpszMsg != '\0')
{
fRet = WriteFile(hStdout, lpszMsg, 1, &cchWritten, NULL);
if( (FALSE == fRet) || (1 != cchWritten) )
return EOF;
lpszMsg++;
}
return 1;
}
#ifdef __cplusplus
}
#endif
y ahora el código de la aplicación que llama:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
#pragma argsused
// A simple program that uses LoadLibrary and
// GetProcAddress to access myPuts from Myputs.dll.
#include <stdio.h>
#include <windows.h>
typedef int (*MYPROC)(LPTSTR);
VOID main(VOID)
{
HINSTANCE hinstLib;
MYPROC ProcAdd,ProcAdd2;
BOOL fFreeResult,fFreeResult2, fRunTimeLinkSuccess=FALSE,fRunTimeLinkSuccess2 = FALSE;
// Get a handle to the DLL module.
hinstLib = LoadLibrary(TEXT("Myputs"));
// If the handle is valid, try to get the function address.
if (hinstLib != NULL)
{
ProcAdd = (MYPROC) GetProcAddress(hinstLib, TEXT("myPuts")); LPVOID lpMsgBuf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),// Default language
(LPTSTR) &lpMsgBuf,0,NULL);
printf( (char*) lpMsgBuf);
system("Pause");
ProcAdd2 = (MYPROC) GetProcAddress(hinstLib, TEXT("changeValue")); FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),// Default language
(LPTSTR) &lpMsgBuf,0,NULL);
printf( (char*) lpMsgBuf);
system("Pause");
// If the function address is valid, call the function.
if (NULL != ProcAdd)
{
fRunTimeLinkSuccess = TRUE;
(ProcAdd) (TEXT("Message via DLL function\n"));
}
if (NULL != ProcAdd2)
{
fRunTimeLinkSuccess2 = TRUE;
(ProcAdd2) (TEXT ("4,true" ) );
}
// Free the DLL module.
fFreeResult2= fFreeResult = FreeLibrary(hinstLib);
}
// If unable to call the DLL function, use an alternative.
if (! fRunTimeLinkSuccess)
{
printf("Message via alternative method\n");
}
if (! fRunTimeLinkSuccess2)
printf("No se pudo invocar a la funcion: changeValue \n");
system("Pause");
}
Las dos lineas en rojo de la aplicación es donde falla porque devuelve NULL, después uso la función GetLastError para buscar el error y es que no la encuentra.
Sobre lo del enlazado estático podrías específicarme en detalles qué es lo que hay que hacer desde C++ Builder. Leí lo que dice la ayuda y lo hice y no me funciona, me da error de linkeo porque no encuentra la entrada de la función en la DLL, algo parecido a lo anterior.
Lo que hice fue:
1) Añadir al proyecto el .Lib de la DLL
2) Ir a las opciones avanzadas de likeo y especificar en el "Delay Load" la el fichero .dll.
Saludos a todos, llevo un mes en esto y no he podido usar funciones de una DLL. No sé que pasa, hago lo mismo que dice la ayuda y nada.