# Call Clarion DLL from C++ and pass \*CString

**URL:** <https://clarionhub.com/t/call-clarion-dll-from-c-and-pass-cstring/7992>\
**Category:** questions\
**Tags:** interop, dll\
**Created:** [March 7, 2025, 9:26pm UTC](https://clarionhub.com/t/call-clarion-dll-from-c-and-pass-cstring/7992 "2025-03-07T21:26:54Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Daniel1](https://clarionhub.com/letter_avatar_proxy/v4/letter/d/b19c9b/32.png) [@Daniel1](https://clarionhub.com/u/Daniel1)\
**Post date:** [March 7, 2025, 9:26pm UTC](https://clarionhub.com/t/call-clarion-dll-from-c-and-pass-cstring/7992/1 "2025-03-07T21:26:54Z")

</div>

Hello All  
I need to call Clarion DLL from C++ app.  
For that purpose, here is console app calling Clarion DLL:

```cpp
#include <windows.h>
#include <iostream>

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

int main() {
    SetConsoleOutputCP(CP_ACP);

    HMODULE hClarionDLL = LoadLibraryA("MyClarion.dll");
    if (!hClarionDLL) {
        std::cerr << "Can not read MyClarion.dll. Error: " << GetLastError() << std::endl;
        return 1;
    }

    ClarionFuncType MyFunction = (ClarionFuncType)GetProcAddress(hClarionDLL, "MyFunction");
    if (!MyFunction) {
        std::cerr << "Function MyFunction not found. Error: " << GetLastError() << std::endl;
        FreeLibrary(hClarionDLL);
        return 2;
    }

    char par1[256] = "Param1";
    char par2[256] = "Param2";
    char par3[256] = "Param3";
    char resultBuffer[1024] = { 0 };

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

    std::cout << "Returned size: " << retLen << std::endl;
    std::cout << "resultBuffer content: " << resultBuffer << std::endl;

    FreeLibrary(hClarionDLL);
    return 0;
}

```

and here is Clarion DLL:

```clarion
  PROGRAM

  MAP
    MyFunction(*cSTRING par1, *cSTRING par2, *cSTRING par3, *CSTRING r1, LONG r2), LONG, PASCAL, NAME('MyFunction')
    
  END

  CODE

MyFunction PROCEDURE(*CSTRING par1, *CSTRING par2, *CSTRING par3, *CSTRING r1, LONG r2)

temp CSTRING(1024)

  CODE
  message('par1: '&clip(par1)&' par2: '&clip(par2)&' par3: '&clip(par3))
  

  

```

As you can see, message display some wired things - instead of Param1, Param2 and Param3, here is what I see:  
 ![image](https://clarionhub.com/images/transparent.png)

---

<div class="post-metadata">

**Author:** ![CarlBarnes](https://clarionhub.com/user_avatar/clarionhub.com/carlbarnes/32/1859_2.png) [@CarlBarnes](https://clarionhub.com/u/CarlBarnes)\
**Post date:** [March 7, 2025, 10:01pm UTC](https://clarionhub.com/t/call-clarion-dll-from-c-and-pass-cstring/7992/2 "2025-03-07T22:01:18Z")

</div>

> [@Daniel1](#):
>
> ```clarion
> MAP
> MyFunction(*cSTRING par1, *cSTRING par2, *cSTRING par3, | 
> *CSTRING r1, LONG r2), LONG, PASCAL, NAME('MyFunction') 
> END
> 
> ```

Try adding RAW to the end of that Map Prototype; otherwise, Clarion includes a parameter with the CString declared size.

Read the Help on RAW. There’s also a topic “Multi Language Programming” with more info on how strings are passed should you want to the prototype to pass the size to Clarion and not use RAW.

```clarion
 MyFunction(*cSTRING par1, *cSTRING par2, *cSTRING par3, | 
            *CSTRING r1, LONG r2),LONG,PASCAL,NAME('MyFunction') , RAW !++ ,Raw
  END

```

* * *

> [@Daniel1](#):
>
> ```clarion
> message('par1: '&clip(par1)&' par2: '&clip(par2)&' par3: '&clip(par3))
> 
> ```

In a Message() you can add a Pipe `|` as shorthand for a `<13,10>` so each parameter appears on its own line making it a little easier to read.

```clarion
Message('par1: '&clip(par1)&'|par2: '&clip(par2)&'|par3: '&clip(par3)) !Pipe=13,10
Message('par1: '&clip(par1)&'<13,10>par2: '&clip(par2)&'<13,10>par3: '&clip(par3)) !same as |

```

---

<div class="post-metadata">

**Author:** ![MarkGoldberg](https://clarionhub.com/user_avatar/clarionhub.com/markgoldberg/32/1511_2.png) [@MarkGoldberg](https://clarionhub.com/u/MarkGoldberg)\
**Post date:** [March 7, 2025, 10:50pm UTC](https://clarionhub.com/t/call-clarion-dll-from-c-and-pass-cstring/7992/3 "2025-03-07T22:50:29Z")

</div>

I’m on my phone atm  
But you can also share an interface between C++ and CW and call either direction with it.

See clarion mag article  
Interfacing with interfaces  
Possibly by Gordon j smith

---

<div class="post-metadata">

**Author:** ![jslarve](https://clarionhub.com/letter_avatar_proxy/v4/letter/j/e480ec/32.png) [@jslarve](https://clarionhub.com/u/jslarve)\
**Post date:** [March 8, 2025, 12:17am UTC](https://clarionhub.com/t/call-clarion-dll-from-c-and-pass-cstring/7992/4 "2025-03-08T00:17:07Z")

</div>

One thing to keep in mind if you use RAW, is that SIZE(pParam) can cause a GPF. So you should avoid using SIZE() in that circumstance.

Pass the size as a separate parameter and ensure that you test the value of the passed data in a safe way, avoiding SIZE().

---

<div class="post-metadata">

**Author:** ![Daniel1](https://clarionhub.com/letter_avatar_proxy/v4/letter/d/b19c9b/32.png) [@Daniel1](https://clarionhub.com/u/Daniel1)\
**Post date:** [March 8, 2025, 7:10am UTC](https://clarionhub.com/t/call-clarion-dll-from-c-and-pass-cstring/7992/5 "2025-03-08T07:10:51Z")

</div>

@CarlBarnes Thanks but RAW doesn’t work. When compiling, it keeps saying: Error : CLARION function cannot use RAW.

---

<div class="post-metadata">

**Author:** ![Daniel1](https://clarionhub.com/letter_avatar_proxy/v4/letter/d/b19c9b/32.png) [@Daniel1](https://clarionhub.com/u/Daniel1)\
**Post date:** [March 8, 2025, 7:16am UTC](https://clarionhub.com/t/call-clarion-dll-from-c-and-pass-cstring/7992/6 "2025-03-08T07:16:42Z")

</div>

@MarkGoldberg Thank you, I found this article on my backup and compiled c++ code together with Clarion DLL

```auto
class ClarionInterface {
public:
    virtual char* getPar1Val() = 0;
    virtual char* getPar2Val() = 0;
    virtual char* getPar3Val() = 0;
};

class ClarionData : public ClarionInterface {
public:
    char Par1Val[256];
    char Par2Val[256];
    char Par3Val[1024];

    virtual char* getPar1Val() { return Par1Val; }
    virtual char* getPar2Val() { return Par2Val; }
    virtual char* getPar3Val() { return Par3Val; }
};

```

but it does not work ☹  
ChatGPT said:  
Clarion DLL cannot use virtual functions from C++ classes, because Clarion does not know the virtual table (v-table) of C++ objects. The virtual function method is not applicable between Clarion DLL and C++ application.

Although you seem to declare INTERFACE correctly in Clarion, Clarion has no way to access these functions if they are virtual functions in C++.

---

<div class="post-metadata">

**Author:** ![Daniel1](https://clarionhub.com/letter_avatar_proxy/v4/letter/d/b19c9b/32.png) [@Daniel1](https://clarionhub.com/u/Daniel1)\
**Post date:** [March 8, 2025, 8:07am UTC](https://clarionhub.com/t/call-clarion-dll-from-c-and-pass-cstring/7992/7 "2025-03-08T08:07:48Z")

</div>

@jslarve  
I’d like to use RAW (it’s something ChatGPT suggested), but Clarion complains when compiling

---

<div class="post-metadata">

**Author:** ![SimonKemp](https://clarionhub.com/letter_avatar_proxy/v4/letter/s/71c47a/32.png) [@SimonKemp](https://clarionhub.com/u/SimonKemp)\
**Post date:** [March 8, 2025, 9:45am UTC](https://clarionhub.com/t/call-clarion-dll-from-c-and-pass-cstring/7992/8 "2025-03-08T09:45:17Z")

</div>

Try “RAW,C” or “RAW,PASCAL” instead of just “RAW”…

---

<div class="post-metadata">

**Author:** ![Daniel1](https://clarionhub.com/letter_avatar_proxy/v4/letter/d/b19c9b/32.png) [@Daniel1](https://clarionhub.com/u/Daniel1)\
**Post date:** [March 8, 2025, 1:43pm UTC](https://clarionhub.com/t/call-clarion-dll-from-c-and-pass-cstring/7992/9 "2025-03-08T13:43:11Z")

</div>

Yes, I tried all possible combinations. The thing is that it is a Clarion function. When it is a function from a DLL, then RAW works.

---

<div class="post-metadata">

**Author:** ![jslarve](https://clarionhub.com/letter_avatar_proxy/v4/letter/j/e480ec/32.png) [@jslarve](https://clarionhub.com/u/jslarve)\
**Post date:** [March 8, 2025, 2:26pm UTC](https://clarionhub.com/t/call-clarion-dll-from-c-and-pass-cstring/7992/10 "2025-03-08T14:26:49Z")

</div>

Hi Daniel - Sorry if I steered you the wrong way. It has been many years since I’ve had to provide a Clarion DLL to a C++ user. I think what we did was provide a STRUCT on their side (a GROUP on our side) that used INT as pointers and for size. I am unable to access that code any more, The procedure definitely used the PASCAL convention, but I believe you are correct that we didn’t use RAW.

---

<div class="post-metadata">

**Author:** ![CarlBarnes](https://clarionhub.com/user_avatar/clarionhub.com/carlbarnes/32/1859_2.png) [@CarlBarnes](https://clarionhub.com/u/CarlBarnes)\
**Post date:** [March 8, 2025, 4:52pm UTC](https://clarionhub.com/t/call-clarion-dll-from-c-and-pass-cstring/7992/11 "2025-03-08T16:52:05Z")

</div>

> [@Daniel1](#):
>
> @CarlBarnes Thanks but RAW doesn’t work. When compiling, it keeps saying: Error : CLARION function cannot use RAW.

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 )`

```clarion
  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.

```cpp
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.

---

<div class="post-metadata">

**Author:** ![Daniel1](https://clarionhub.com/letter_avatar_proxy/v4/letter/d/b19c9b/32.png) [@Daniel1](https://clarionhub.com/u/Daniel1)\
**Post date:** [March 8, 2025, 9:12pm UTC](https://clarionhub.com/t/call-clarion-dll-from-c-and-pass-cstring/7992/12 "2025-03-08T21:12:39Z")

</div>

@CarlBarnes First option works fabulous, thank you very much.

---

<div class="post-metadata">

**Author:** ![ironmansculler](https://clarionhub.com/user_avatar/clarionhub.com/ironmansculler/32/5421_2.png) [@ironmansculler](https://clarionhub.com/u/ironmansculler)\
**Post date:** [March 12, 2025, 1:41am UTC](https://clarionhub.com/t/call-clarion-dll-from-c-and-pass-cstring/7992/13 "2025-03-12T01:41:03Z")

</div>

use the COM attribute… this is example of a complex CPP interface that hooks clarion into CPP and lets you merge the platforms together…

! UBS Get Set Data Methods declared in clarion.  
! You include this interface in your clarion class.

Datamodels class,type,implements(IUBSD)  
! clarion methods and the CPP iUBSD interface working together.  
END

```clarion
IUBSD INTERFACE,com  
  
your clarion methods for the CPP virtual class

SetCstring procedure(const *Cstring CstringData)

                    End

// in your CPP project.
 
class IUBS
{

public:
 
	virtual long _STD SetCstring(const *char) =0;      
};

1). create a class with the above interface.
2). create an instance of the class and return the Interface to clarion.

IUBSClassInstance : public IUBS
{
public:

// method of IUBS interface.
  ect... plenty of examples on learning CPP or more complex site.

} 

// create your external class instance and make your CPP project a dll
// and now your CPP code is part of your clarion application and your classes
// can call each other. you marshal the data.  

// The CPP external procedure callable from Clarion.
// You need to declare this external procedure as a module in clarion and also make a lib for your CPP DLL. It may all seem a bit of a drama but its pretty simply really and a lot easier than call clarion from DOT NET where its a nightmare of marshal delegates and data types.

! Clarion declaration to call your CPP procedure or function to return your new CPP class interface.

   module('CPP DLL NAME')
        createIUBS().*IUBS,name('createIUBS'),C,RAW
  END

// CPP method to call from clarion to create your new class container and return the interface.

extern "C" IUBS *createIUBS()
{
    return new IUBSClassInstance();
}

```

You can make this example as complex as you like.

In your clarion class declare an instance of the CPP interface.  
In your clarion class assign a instance of the ref from the CPP createIUBS.  
myclass.IUBSDref &= createIUBS()

You will need to create another method in CPP to take the address of the class to delete it later on and pass the interface to it or the address of the new CPP class you created.

Now your free of DOT NET.

COM in clarions is the pascal stack passing and on your CPP declare your abstract CPP class methods as \_STD.

sorry forgot how this forum formats its text..

---

<div class="post-metadata">

**Author:** ![jslarve](https://clarionhub.com/letter_avatar_proxy/v4/letter/j/e480ec/32.png) [@jslarve](https://clarionhub.com/u/jslarve)\
**Post date:** [March 12, 2025, 2:03am UTC](https://clarionhub.com/t/call-clarion-dll-from-c-and-pass-cstring/7992/14 "2025-03-12T02:03:31Z")

</div>

three graves accents and the word “clarion” starts the block.

Then terminate the block with 3 more graves accents.

---

<div class="post-metadata">

**Author:** ![Daniel1](https://clarionhub.com/letter_avatar_proxy/v4/letter/d/b19c9b/32.png) [@Daniel1](https://clarionhub.com/u/Daniel1)\
**Post date:** [March 12, 2025, 6:00am UTC](https://clarionhub.com/t/call-clarion-dll-from-c-and-pass-cstring/7992/15 "2025-03-12T06:00:22Z")

</div>

> [@ironmansculler](#):
>
> use the COM attribute… this is example of a complex CPP interface that hooks clarion into CPP and lets you merge the platforms together

This is interesting thank you.  
Do you have small CPP example?

---

<div class="post-metadata">

**Author:** ![ironmansculler](https://clarionhub.com/user_avatar/clarionhub.com/ironmansculler/32/5421_2.png) [@ironmansculler](https://clarionhub.com/u/ironmansculler)\
**Post date:** [March 12, 2025, 11:39pm UTC](https://clarionhub.com/t/call-clarion-dll-from-c-and-pass-cstring/7992/16 "2025-03-12T23:39:44Z")

</div>

Have update the above topic with an example.

---

<div class="post-metadata">

**Author:** ![Daniel1](https://clarionhub.com/letter_avatar_proxy/v4/letter/d/b19c9b/32.png) [@Daniel1](https://clarionhub.com/u/Daniel1)\
**Post date:** [March 13, 2025, 5:32am UTC](https://clarionhub.com/t/call-clarion-dll-from-c-and-pass-cstring/7992/17 "2025-03-13T05:32:31Z")

</div>

Thank you so much for details you shared.

---

<div class="post-metadata">

**Author:** ![ironmansculler](https://clarionhub.com/user_avatar/clarionhub.com/ironmansculler/32/5421_2.png) [@ironmansculler](https://clarionhub.com/u/ironmansculler)\
**Post date:** [March 14, 2025, 2:14am UTC](https://clarionhub.com/t/call-clarion-dll-from-c-and-pass-cstring/7992/18 "2025-03-14T02:14:23Z")

</div>

dont forget to make sure your prototypes match as i left of the return long on the clarion definition. If any prototype has a mismatch return type the clarion stack state is fussy and may not be in a stable state.

---

<div class="post-metadata">

**Author:** ![Daniel1](https://clarionhub.com/letter_avatar_proxy/v4/letter/d/b19c9b/32.png) [@Daniel1](https://clarionhub.com/u/Daniel1)\
**Post date:** [March 16, 2025, 4:45pm UTC](https://clarionhub.com/t/call-clarion-dll-from-c-and-pass-cstring/7992/19 "2025-03-16T16:45:32Z")

</div>

@ironmansculler do you have any example, maybe just one procedure example of both C++ and Clarion side, please?

In the meantime, I’m struggling with new problem:  
This C++ DLL code (below) I need on Clarion side (also as DLL). I even don’t know where to start. In theory, it should receive one string parameter. Thanks for your ideas.

```auto
extern "C" __declspec(dllexport) BSTR__stdcall Test_ProcessData(BSTR input)
{
    // suffix for input string.
    CComBSTR bstrSuffix(L" - Processed by Test.dll");

    int inputLen = SysStringLen(input);
    int suffixLen = SysStringLen(bstrSuffix);
    int totalLen = inputLen + suffixLen;

    BSTR bstrResult = SysAllocStringLen(NULL, totalLen);
    if (bstrResult)
    {
        memcpy(bstrResult, input, inputLen * sizeof(wchar_t));
        memcpy(bstrResult + inputLen, bstrSuffix, suffixLen * sizeof(wchar_t));
    }

    return bstrResult;
}

```

---

<div class="post-metadata">

**Author:** ![ironmansculler](https://clarionhub.com/user_avatar/clarionhub.com/ironmansculler/32/5421_2.png) [@ironmansculler](https://clarionhub.com/u/ironmansculler)\
**Post date:** [March 16, 2025, 9:16pm UTC](https://clarionhub.com/t/call-clarion-dll-from-c-and-pass-cstring/7992/21 "2025-03-16T21:16:08Z")

</div>

example of typed functions in clarion 6 to 10. Clarion 11 has special function pointer handling that supports C style function pointers. These proto types can be called as delegates from say DOT NET or in theory CPP. bstring is what your looking for. const \*cstring as everyone knows. bstring in clarion is not in the help index but its there and works.

the examples below are derived from early example of Gordon Smith calling a function pointer as a faked thunk by address i think calling CPP.  
Clarion supported typed functions since early days of the windows compiler.

Notice this “ **csEventdelegate ptr** ,”. and where it is used to thunk the call. “**return ptr(**”

```auto

This is an example of typed functions. 

 module('Clacalcscriptwin32.clw')
 
    TypeCalcscriptcontext(long appidNo, long eventno, bstring membernames, bstring propertyvalue),type,pascal,name('typecalcscriptcontext') ! delegate for event context event id     
    TypeCalcscriptcallback(long appidNo, long eventno, bstring membernames, bstring propertyvalue),TYPE ,pascal! calc script call back

Now in your example all you need is a clarion function typed external as a 
bstring and of course a lib file to go with it.

For more complex examples of function call backs in
 Clarion 6 to 10 where it may be required and mostly 
clarion developers dont do callbacks from say DOT NET to
 Clarion and call backs back to dot net but you can do it and
 this is generic for even VB Dot Net delegates.

Now lets look at function call backs and how they are
 prototyped in releases 6 to 10. 

    Module('callfunctionptr.clw')
           
       csEventdelegate(long appidNo,Long EventId,bstring Boundname,bstring membername,bstring Propertyvalue,long paramscount),byte,PASCAL ,TYPE
    callcsEventptr(csEventdelegate ptr,long appidNo,Long EventId,bstring Boundname,bstring membername,bstring Propertyvalue,long paramscount),pascal,BYTE,Proc,Name('callcsEventptr')  
  
 
 
           END
 
! the thunked call example, remember in clarion 11 
you dont need to do this call by address.
! ptr is the address of the external function to call.

callcsEventptr Function( ptr,long appidNo,Long EventId,bstring Boundname,bstring membername,bstring Propertyvalue,long paramscount) 
    CODE
! Pre clarion 11 call by address.
    return ptr(appidNo, EventId, Boundname, membername, Propertyvalue,paramscount)
```
