Call Clarion DLL from C++ and pass *CString

Two ideas … In Clarion prototype *CSTRING as LONG and it will get the address of the CString. Then Ref assign &= it to a &CSTRING Reference variable.

I changed R2 to be named r1_Size as in the call its passed sizeof(resultBuffer) / sizeof(char). Clarion allows a Reference to define the size with &= ( Address &':'& Size )

  MAP
    MyFunction(LONG par1_Addr, LONG par2_Addr, LONG par3_Addr, | 
               LONG r1_Addr, LONG r1_Size), LONG, PASCAL, NAME('MyFunction') 
  END
  
MyFunction PROCEDURE(LONG par1_Addr, LONG par2_Addr, LONG par3_Addr, | 
                     LONG r1_Addr, LONG r1_Size)
par1   &CSTRING 
par2   &CSTRING 
par3   &CSTRING 
r1     &CSTRING 
  CODE
  par1 &= (par1_Addr)   !Reference assign address to &CSTRING
  par2 &= (par2_Addr)
  par3 &= (par3_Addr)
  r1   &= (r1_Addr &':'& r1_Size)  !Was R2 which appears to be Size(R1) ?
  message('1_Addr: '&par1_Addr &'|2_Addr: '&par2_Addr &'|3_Addr: '&par3_Addr &'|r1_Addr: '&r1_Addr &'  Size: '& r1_Size)
  message('par1:   '&clip(par1)&'|par2:   '&clip(par2)&'|par3:   '&clip(par3))

Option 2 … In C++ prototype to pass the size before each *Char and pass it kind of like below.

typedef int(__stdcall* ClarionFuncType)(int, char*, int, char*, int, char*, int, char*, int);

...
int retLen = MyFunction(sizeof(par1), par1, sizeof(par2), par2, sizeof(par3), par3, sizeof(resultBuffer), resultBuffer, sizeof(resultBuffer) / sizeof(char));

This is safer so Clarion would have the size and not overrun the end. If you do not need to modify these you could add CONST *CSTRING par1 so the compiler prevents changes.

2 Likes