Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2024-10

How do I pass a call back Class and its method to an external library *.so file writting in C++

4 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Dennis

Dear All,

I am given an API linux library *.so file written in C++. It was expected to be consume by a program written in C++. However, I would like to write such a program in Free Pascal.

The given header file is:
#ifndef ApiProxyWrapperReplyH
#define ApiProxyWrapperReplyH
//--------------------------------------------------------------------------- #include <stdio.h>
#include "SPApiProxyDataType.h"
class ApiProxyWrapperReply {

public:
     ApiProxyWrapperReply(void){};
     ~ApiProxyWrapperReply(void){};
     virtual void OnLoginReply(char *user_id, long ret_code,char
*ret_msg) = 0;
     virtual void OnConnectedReply(long host_type,long con_status) = 0;
     virtual void OnApiOrderRequestFailed(tinyint action, const
SPApiOrder *order, long err_code, char *err_msg) = 0;
     virtual void OnApiOrderReport(long rec_no, const SPApiOrder *order)
= 0;
     virtual void OnApiOrderBeforeSendReport(const SPApiOrder *order) = 0;
     virtual void OnAccountLoginReply(char *accNo, long ret_code, char*
ret_msg) = 0;
     virtual void OnAccountLogoutReply(char *accNo, long ret_code, char*
ret_msg) = 0;
     virtual void OnAccountInfoPush(const SPApiAccInfo *acc_info) = 0;
     virtual void OnAccountPositionPush(const SPApiPos *pos) = 0;
     virtual void OnUpdatedAccountPositionPush(const SPApiPos *pos) = 0;
     virtual void OnUpdatedAccountBalancePush(const SPApiAccBal
*acc_bal) = 0;
     virtual void OnApiTradeReport(long rec_no, const SPApiTrade *trade)
= 0;
     virtual void OnApiPriceUpdate(const SPApiPrice *price) = 0;
     virtual void OnApiTickerUpdate(const SPApiTicker *ticker) = 0;
     virtual void OnPswChangeReply(long ret_code, char *ret_msg) = 0;
     virtual void OnProductListByCodeReply(long req_id, char *inst_code,
bool is_ready, char *ret_msg) = 0;
     virtual void OnInstrumentListReply(long req_id, bool is_ready, char
*ret_msg) = 0;
     virtual void OnBusinessDateReply(long business_date) = 0;
     virtual void OnApiMMOrderBeforeSendReport(SPApiMMOrder *mm_order) = 0;
     virtual void OnApiMMOrderRequestFailed(SPApiMMOrder *mm_order, long
err_code, char *err_msg) = 0;
     virtual void OnApiQuoteRequestReceived(char *product_code, char
buy_sell, long qty) = 0;
     virtual void OnApiAccountControlReply(long ret_code, char *ret_msg)
= 0;
     virtual void OnApiLoadTradeReadyPush(long rec_no, const SPApiTrade
*trade) = 0;
};

#endif

I am expected to create and pass an instance of such class ApiProxyWrapperReply in my calling program
 via a function
void SPAPI_RegisterApiProxyWrapperReply(ApiProxyWrapperReply* apiProxyWrapperReply);

and the external library will then call the various methods of ApiProxyWrapperReply  as 'call-back' functions when needed.

I consulted co-pilot but it failed to teach me how to do so in a Free Pascal program calling such an external library.

Please kindly help.

Dennis Poon

Reply by email

Sven Barth
to Dennis

Dennis via fpc-pascal schrieb am Fr., 4.
Okt. 2024, 08:40:

Show quoted text 5 lines
Dear All, I am given an API linux library *.so file written in C++. It was expected to be consume by a program written in C++. However, I would like to write such a program in Free Pascal.

[snip]

Show quoted text 9 lines
I am expected to create and pass an instance of such class ApiProxyWrapperReply in my calling program via a function void SPAPI_RegisterApiProxyWrapperReply(ApiProxyWrapperReply* apiProxyWrapperReply); and the external library will then call the various methods of ApiProxyWrapperReply as 'call-back' functions when needed.

Considering that the class only has abstract virtual methods and the destructor is non-virtual you *might* be able to do this by declaring a raw interface ({$Interfaces Corba}) and declaring all the virtual methods in the same order (very important!) with suitable signatures and calling convention (for i386 you should pick cppdecl otherwise the system default should be alright), implementing that interface in some Object Pascal class and then passing an instance of that interface to the library.

It could still go wrong due to some differences in the ABI, but it might just as well work. 🤷‍♀️

I consulted co-pilot but it failed to teach me how to do so in a Free Pascal program calling such an external library.

Shows that the current state of "AI" can't help with every obscure topic 😅

Regards,
Sven

Reply by email

Dennis
to Sven Barth
Show quoted text 24 lines
I am expected to create and pass an instance of such class ApiProxyWrapperReply in my calling program   via a function void SPAPI_RegisterApiProxyWrapperReply(ApiProxyWrapperReply* apiProxyWrapperReply); and the external library will then call the various methods of ApiProxyWrapperReply  as 'call-back' functions when needed. Considering that the class only has abstract virtual methods and the destructor is non-virtual you *might* be able to do this by declaring a raw interface ({$Interfaces Corba}) and declaring all the virtual methods in the same order (very important!) with suitable signatures and calling convention (for i386 you should pick cppdecl otherwise the system default should be alright), implementing that interface in some Object Pascal class and then passing an instance of that interface to the library. It could still go wrong due to some differences in the ABI, but it might just as well work. 🤷‍♀️

In C++, I was expected to pass the class instance to the external library. So, In Pascal, do I pass the interface variable to the external library?

Thanks a lot.

Dennis Poon

Reply by email

Sven Barth
to Dennis

Dennis via fpc-pascal schrieb am Mo., 21.
Okt. 2024, 05:09:

Show quoted text 26 lines
> I am expected to create and pass an instance of such class > ApiProxyWrapperReply in my calling program > via a function > void SPAPI_RegisterApiProxyWrapperReply(ApiProxyWrapperReply* > apiProxyWrapperReply); > > and the external library will then call the various methods of > ApiProxyWrapperReply as 'call-back' functions when needed. > Considering that the class only has abstract virtual methods and the destructor is non-virtual you *might* be able to do this by declaring a raw interface ({$Interfaces Corba}) and declaring all the virtual methods in the same order (very important!) with suitable signatures and calling convention (for i386 you should pick cppdecl otherwise the system default should be alright), implementing that interface in some Object Pascal class and then passing an instance of that interface to the library. It could still go wrong due to some differences in the ABI, but it might just as well work. 🤷‍♀️ In C++, I was expected to pass the class instance to the external library. So, In Pascal, do I pass the interface variable to the external library?

Correct. As I said however: it *might* work, no guarantee.

Regards,
Sven

Reply by email