0Day Forums
Wrapping a C++ object in extern "C" - Printable Version

+- 0Day Forums (https://0day.red)
+-- Forum: Coding (https://0day.red/Forum-Coding)
+--- Forum: C & C++ (https://0day.red/Forum-C-C)
+--- Thread: Wrapping a C++ object in extern "C" (/Thread-Wrapping-a-C-object-in-extern-quot-C-quot)



Wrapping a C++ object in extern "C" - overstowed397786 - 07-26-2023

consider a simple example class:

class BankAccount {
public:
BankAccount() { balance =0.0; };
~BankAccount() {};
void deposit(double amount) {
balance += amount;
}
private:
double balance;
};

Now say I want to wrap this in extern "C" so that I can call it from many different programming languages such as C# and Java.
I tried the following which seemed to work:

// cbankAccount.h:
extern "C" unsigned long createBackAccount();
extern "C" void deposit(unsigned long bankAccount, double amount);
// cbankAccount.cpp
unsigned long createBackAccount() {
BankAccount *b = new BankAccount();
return (unsigned long) b;
}
void deposit(unsigned long bankAccount, double amount) {
BankAccount *b = (BankAccount*) bankAccount;
b->deposit(amount);
}
Is this portable?
Is the type unsigned "unsigned long" large enough for an object pointer?
Any other problems with this approach?

Thank in advance for any answers!









RE: Wrapping a C++ object in extern "C" - drucill663 - 07-26-2023

This is not portable, because `unsigned long` may be not long enough for a pointer. A not so rare platform where this happens is win64.

Better to use `ptrdiff_t` or `void*`.


RE: Wrapping a C++ object in extern "C" - begirding248710 - 07-26-2023

Yeah. It's bad. Really bad. `unsigned long`- just no. Return a properly typed `BankAccount*`- the other languages will see it on the other end as a generic pointer (such as System.IntPtr) and there's no need to return an untyped pointer when the binary interface doesn't type pointers anyway.

extern "C" BankAccount* CreateBankAccount() {
return new BankAccount;
}
extern "C" void deposit(BankAccount* account, double amount) {
account->deposit(amount);
}


RE: Wrapping a C++ object in extern "C" - hartzel524 - 07-26-2023

It would probably be platform dependent whether long is large enough (probably not on x86-64) an alternative is to use something like [swig][1]


[1]:

[To see links please register here]




RE: Wrapping a C++ object in extern "C" - annotations971814 - 07-26-2023

I'd use void* instead of unsigned long.


RE: Wrapping a C++ object in extern "C" - caroche12 - 07-26-2023

That basically looks fine with one proviso. Trying to use an integer type to hold a pointer is not a great idea—much better to use `void*` since that, by definition, is the width of a pointer.


----------
Actually, I think @DeadMG's answer is a cleaner approach than this.




RE: Wrapping a C++ object in extern "C" - Sirluxurist393 - 07-26-2023

Type-strong is even better than void *.

typedef struct BankAccountProxy * BankAccountPtr;

BankAccountPtr createBackAccount() {
BankAccount *b = new BankAccount();
return (BankAccountPtr) b;
}