Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Passing strings back from a C++ DLL function

Status
Not open for further replies.

jpm3

IS-IT--Management
Apr 28, 2003
17
US
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

Code:
#include "stdafx.h"
#include "resource.h"
#include <initguid.h>
#include &quot;SUPER.h&quot;

#include &quot;SUPER_i.c&quot;

#import &quot;c:\program files\common files\system\ado\msado15.dll&quot; rename (&quot;EOF&quot;,&quot;adoEOF&quot;) 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 &quot;C&quot;
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&quot;driver={sql server};SERVER=(local);Database=pubs;&quot;
 //                                 L&quot;UID=sa; PWD=;&quot;; 
         spCON->ConnectionString =L&quot;DRIVER={Microsoft Access Driver (*.mdb)};&quot;
			                      L&quot;DBQ=SuperCombo.mdb;DefaultDir=C:\\WINNT;&quot;; 
             
        spCON->Open( &quot;&quot;, &quot;&quot;, &quot;&quot;, -1 );
        CREATEiNSTANCE(spRS,Recordset) 
        spRS->PutRefActiveConnection( spCON );

        spRS->Open(&quot;SELECT netProfit, canTradePct From SuperCombo WHERE dBegin <= #06/12/2003# AND dEnd >= #06/12/2003#&quot;, 
			vtMissing, adOpenKeyset, adLockBatchOptimistic, -1);
		
		
        if (spRS->adoEOF == false)
		{
 //           printf(&quot;au_lname = %s  au_fname = %s \n&quot;, UC _bstr_t(RsITEM(spRS,0L)), UC _bstr_t(RsITEM(spRS,&quot;au_fname&quot;)));
		vNetProfit = UC _bstr_t(RsITEM(spRS,&quot;netProfit&quot;));
        vReturn = lngDate;
        }
        spRS->Close();
        spCON->Close();
       
    }
    catch( _com_error &e){
        _bstr_t bstrSource(e.Source());
        _bstr_t bs =  _bstr_t(&quot; Error: &quot;) + _bstr_t(e.Error()) + _bstr_t(&quot; Msg: &quot;) 
            + _bstr_t(e.ErrorMessage()) + _bstr_t(&quot; Description: &quot;) 
            + _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 = &quot;000&quot;
retVal = FNSUPERCOMBO(19581125, vnp)
MsgBox (Str(retVal) + &quot;: &quot; + vnp)
End Sub

 
Your first question (coverting long to string):
Code:
   CString convertDateInLong(
         long aLong
   ) {
      CString ret = _T(&quot;&quot;);
      ret.Format(
            _T(&quot;%02d/%02d/%02d&quot;)
         ,  aLong % 100
         ,  (aLong % 10000) / 100
         ,  aLong / 10000
      );
      return ret;
   }
Whoops, that's for European dates.
Try this:
Code:
   CString convertDateInLong(
         long aLong
   ) {
      CString ret = _T(&quot;&quot;);
      ret.Format(
            _T(&quot;%d/%02d/%02d&quot;)
         ,  (aLong % 10000) / 100
         ,  aLong % 100
         ,  aLong / 10000
      );
      return ret;
   }
Which will work for that strange date format they use on the other side of the Atlantic from me. [smile]

________________________________________
[hippy]Roger J Coult; Grimsby, UK
In the game of life the dice have an odd number of sides.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top