I'm trying to use an exported DLL function to pass in a date (as a long) and pass back a factor from an ACCESS table for that date.
** How do I convert the long I pass in (20030612) to the string "6/12/2003" ??
** I only found a define that extracts ADO recordset fields as variants and converts them to char, so I changed the numeric fields to string types (TEXT in Access). Do I need a pointer to send them back to the calling program?? Is it easier to stick with doubles? safearrays?? If it would just return "975", 975 or 9.75 (the netProfit field for 6/12/2003) or any likeness thereof I would be relieved.
** How do set up the workspace to debug your DLL line by line?
It's hard to find an appropriate example and greatly appreciate any help. My code is attached.
Thanks again--
John
VB:
** How do I convert the long I pass in (20030612) to the string "6/12/2003" ??
** I only found a define that extracts ADO recordset fields as variants and converts them to char, so I changed the numeric fields to string types (TEXT in Access). Do I need a pointer to send them back to the calling program?? Is it easier to stick with doubles? safearrays?? If it would just return "975", 975 or 9.75 (the netProfit field for 6/12/2003) or any likeness thereof I would be relieved.
** How do set up the workspace to debug your DLL line by line?
It's hard to find an appropriate example and greatly appreciate any help. My code is attached.
Thanks again--
John
Code:
#include "stdafx.h"
#include "resource.h"
#include <initguid.h>
#include "SUPER.h"
#include "SUPER_i.c"
#import "c:\program files\common files\system\ado\msado15.dll" rename ("EOF","adoEOF") no_namespace
#define CREATEiNSTANCE(sp,riid) { HRESULT _hr =sp .CreateInstance( __uuidof( riid ) ); if (FAILED(_hr)) _com_issue_error(_hr); }
#define RsITEM(rs,x) rs->Fields->Item[_variant_t(x)]->Value
#define UC (char *)
//#define UC (int )
struct InitOle {
InitOle() { ::CoInitialize(NULL); }
~InitOle() { ::CoUninitialize(); }
} _init_InitOle_; // Global Instance to force load/unload of OLE
CComModule _Module;
BEGIN_OBJECT_MAP(ObjectMap)
END_OBJECT_MAP()
/////////////////////////////////////////////////////////////////////////////
// DLL Entry Point
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
_Module.Init(ObjectMap, hInstance, &LIBID_SUPERLib);
DisableThreadLibraryCalls(hInstance);
}
else if (dwReason == DLL_PROCESS_DETACH)
_Module.Term();
return TRUE; // ok
}
/////////////////////////////////////////////////////////////////////////////
// Used to determine whether the DLL can be unloaded by OLE
STDAPI DllCanUnloadNow(void)
{
return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// Returns a class factory to create an object of the requested type
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
return _Module.GetClassObject(rclsid, riid, ppv);
}
/////////////////////////////////////////////////////////////////////////////
// DllRegisterServer - Adds entries to the system registry
STDAPI DllRegisterServer(void)
{
// registers object, typelib and all interfaces in typelib
return _Module.RegisterServer(TRUE);
}
/////////////////////////////////////////////////////////////////////////////
// DllUnregisterServer - Removes entries from the system registry
STDAPI DllUnregisterServer(void)
{
return _Module.UnregisterServer(TRUE);
}
// This is an example of an exported function.
int _stdcall FNSUPERCOMBO(int lngDate, char *vNetProfit)
{
_RecordsetPtr spRS;
_ConnectionPtr spCON;
int vReturn;
vReturn = 999;
try{
CREATEiNSTANCE(spCON,Connection);
// spCON->ConnectionString = L"driver={sql server};SERVER=(local);Database=pubs;"
// L"UID=sa; PWD=;";
spCON->ConnectionString =L"DRIVER={Microsoft Access Driver (*.mdb)};"
L"DBQ=SuperCombo.mdb;DefaultDir=C:\\WINNT;";
spCON->Open( "", "", "", -1 );
CREATEiNSTANCE(spRS,Recordset)
spRS->PutRefActiveConnection( spCON );
spRS->Open("SELECT netProfit, canTradePct From SuperCombo WHERE dBegin <= #06/12/2003# AND dEnd >= #06/12/2003#",
vtMissing, adOpenKeyset, adLockBatchOptimistic, -1);
if (spRS->adoEOF == false)
{
// printf("au_lname = %s au_fname = %s \n", UC _bstr_t(RsITEM(spRS,0L)), UC _bstr_t(RsITEM(spRS,"au_fname")));
vNetProfit = UC _bstr_t(RsITEM(spRS,"netProfit"));
vReturn = lngDate;
}
spRS->Close();
spCON->Close();
}
catch( _com_error &e){
_bstr_t bstrSource(e.Source());
_bstr_t bs = _bstr_t(" Error: ") + _bstr_t(e.Error()) + _bstr_t(" Msg: ")
+ _bstr_t(e.ErrorMessage()) + _bstr_t(" Description: ")
+ _bstr_t(e.Description());
MessageBox(0,bs,bstrSource, MB_OK);
}
return vReturn;
}
VB:
Code:
Private Sub Command1_Click()
Dim retVal As Long
Dim vnp As String
vnp = "000"
retVal = FNSUPERCOMBO(19581125, vnp)
MsgBox (Str(retVal) + ": " + vnp)
End Sub