|
-
August 2nd, 2011, 02:24 PM
#16
Re: How to call a C++ dll function at runtime ?
I think I get it now. My mistake was thinking that I could index the function pointer as one usually can do with a pointer, but that is not the case. Simply capturing the pointer returned by the function allows complete pointer indexing, and a single call to cleanup the pointer suffices. This little example works to return a vector from a dll using runtime dynamic linking without a memory leak.
Code:
///////////////////////////////////////////////////////////////////////////////
// mydll.h
#ifdef MY_EXPORTS
#define MY_API __declspec(dllexport)
#else
#define MY_API __declspec(dllimport)
#endif
extern MY_API double * pVector;
// Get rid of name mangeling
extern "C"
{
MY_API double * fvec(void);
MY_API void clean(double * dp);
}
////////////////////////////////////////////////////////////////////////////////////
// mydll.cpp
#include "stdafx.h"
#include "my.h"
MY_API double * pVector;
double * CreateVector(int nSize)
{
// Allocate memory including leading size containing byte
pVector = new double [nSize + 1];
memset(pVector, 0x00, nSize+1);
return pVector;
}// CreateVector(int nSize)
void FreeVector(double * pVector)
{
delete [] pVector;
pVector = NULL;
}// FreeVector(double * pVector)
MY_API double * fvec(void)
{
pVector = CreateVector(8);
pVector[0] = 8.0;
pVector[1] = 6.4342;
pVector[2] = 1.5453;
pVector[3] = 2.6546;
pVector[4] = 3.7657;
pVector[5] = 4.23423;
pVector[6] = 5.1232;
pVector[7] = 6.87654;
pVector[8] = 7.7755;
return pVector;
}
MY_API void clean(double * dp)
{
if(dp != NULL)
{
delete [] dp;
dp = NULL;
}
}
/////////////////////////////////////////////////////////////////////////////////////////
// test.cpp
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
// Function pointers that will be used for the DLL functions.
typedef double *(*FVEC)();
typedef void (*CLEAN)(double *);
int _tmain(int argc, _TCHAR* argv[])
{
int iOrg = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
_CrtSetDbgFlag(iOrg | _CRTDBG_LEAK_CHECK_DF);
vector<double> vf;
HINSTANCE hinstLib;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
FVEC _MYVEC = NULL;
CLEAN _MYCLEAN = NULL;
// Get a handle to the DLL module.
hinstLib = LoadLibrary(TEXT("my.dll"));
if (NULL != _MYVEC)
{
printf("\n_MYVEC is not NULL\n\n");
fRunTimeLinkSuccess = TRUE;
double * pVec = NULL;
// get vector
pVec = _MYVEC();
int N = (int) pVec[0];
vf.resize(N);
for(int i=1; i <= N; i++)
{
vf[i-1] = pVec[i];
}
printf("\n");
_MYCLEAN(pVec);
for(size_t i = 0; i < vf.size(); i++) { printf("%0.4f\n", vf[i]); }
} }
// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);
}
// If unable to call the DLL function, use an alternative.
if (! fRunTimeLinkSuccess)
printf("Unable to call the DLL function\n");
for(size_t i = 0; i < vf.size(); i++) { printf("%0.4f\n", vf[i]); }
return 0;
}
Output:
Handle is valid
_MYVEC is not NULL
6.4342
1.5453
2.6546
3.7657
4.2342
5.1232
6.8765
7.7755
Thank you all for your kind help and patience with a slow learner.
Last edited by Mike Pliam; August 2nd, 2011 at 03:22 PM.
mpliam
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|