0

I'm new to using RAD Studio as I currently have to use it for this current project. What I am trying to do is call functions defined in a DLL file which I generated in Visual Studio in a RAD Studio C++ project .

Following the advice from this question below Using Visual Studio DLL in Embarcadero RAD Studio XE? I have converted the C++ DLL file I have generated from Visual Studio to a supported file for RAD studio using their command:

mkexp pub-sub-sample.a pub-sub-sample.dll

I can verify that my functions have been exported as I did the command dump.

Turbo Dump  Version 6.5.4.0 Copyright (c) 1988-2016 Embarcadero Technologies, Inc.
                Display of File pub-sub-sample.dll

EXPORT ord:0001='?DisconnectCallback@PubSub@samples@awsiotsdk@@IEAA?AW4ResponseCode@3@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$shared_ptr@VDisconnectCallbackContextData@awsiotsdk@@@6@@Z'
EXPORT ord:0002='?GetCurrentPath@ConfigCommon@awsiotsdk@@SA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ'
EXPORT ord:0003='?InitializeCommon@ConfigCommon@awsiotsdk@@SA?AW4ResponseCode@2@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z'
EXPORT ord:0004='?InitializeTLS@PubSub@samples@awsiotsdk@@IEAA?AW4ResponseCode@3@XZ'
EXPORT ord:0005='?LogParseError@ConfigCommon@awsiotsdk@@KAXAEBW4ResponseCode@2@AEBV?$GenericDocument@U?$UTF8@D@rapidjson@@V?$MemoryPoolAllocator@VCrtAllocator@rapidjson@@@2@VCrtAllocator@2@@rapidjson@@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z'
EXPORT ord:0006='?ReconnectCallback@PubSub@samples@awsiotsdk@@IEAA?AW4ResponseCode@3@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$shared_ptr@VReconnectCallbackContextData@awsiotsdk@@@6@W443@@Z'
EXPORT ord:0007='?ResubscribeCallback@PubSub@samples@awsiotsdk@@IEAA?AW4ResponseCode@3@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$shared_ptr@VResubscribeCallbackContextData@awsiotsdk@@@6@W443@@Z'
EXPORT ord:0008='?RunPublish@PubSub@samples@awsiotsdk@@IEAA?AW4ResponseCode@3@H@Z'
EXPORT ord:0009='?RunSample@PubSub@samples@awsiotsdk@@QEAA?AW4ResponseCode@3@XZ'
EXPORT ord:0010='?Subscribe@PubSub@samples@awsiotsdk@@IEAA?AW4ResponseCode@3@XZ'
EXPORT ord:0011='?SubscribeCallback@PubSub@samples@awsiotsdk@@IEAA?AW4ResponseCode@3@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@0V?$shared_ptr@VSubscriptionHandlerContextData@mqtt@awsiotsdk@@@6@@Z'
EXPORT ord:0012='?Unsubscribe@PubSub@samples@awsiotsdk@@IEAA?AW4ResponseCode@3@XZ'

And also that it's building and running under a visual studio project where I can call the RunSample() function from the generated DLL file.

#include <iostream>
#include "PubSub.hpp"

int main()
{
    awsiotsdk::samples::PubSub object1;
    object1.RunSample();
}

My question is how can I port the example code above to run in a RAD studio C++ project? I tried using extern "C" __declspec(dllimport) in front of awsiotsdk::samples::PubSub object1 but it wasn't working.

Ken White
  • 123,280
  • 14
  • 225
  • 444
Sahil Bora
  • 173
  • 1
  • 12
  • For interoperability between compilers, you should not use things like classes, namespaces, etc. Things that are not portable, are not name-mangled the same way by different vendors, etc. You should only export things that are compatible with C. So, that means re-writing your DLL to flatten things out using simple names, using `extern "C"`, using POD types, etc – Remy Lebeau Jan 09 '20 at 20:33
  • Unfortunately I don't have a choice because it's the Amazon AWS C++ SDK that I have generated a DLL that I need running in the rad studio C++ project. – Sahil Bora Jan 09 '20 at 20:44
  • Then it won't work as-is in C++Builder. You will have to wrap your desired SDK operations inside a Visual Studio DLL that exports a C-compatible interface for C++Builder to use. Unless you can re-compile the SDK source code directly in C++Builder instead of in Visual Studio, that is. – Remy Lebeau Jan 09 '20 at 20:47
  • The entire Amazon AWS C++ SDK source files have been written in visusl studio, which uses entirely classes and namespaces. I'm not liking the chances of it building successful in RAD studio as a DLL. – Sahil Bora Jan 09 '20 at 20:53
  • Then wrapping it inside a Visual Studio DLL with C-compatible exports is the only viable option. – Remy Lebeau Jan 09 '20 at 20:56
  • https://stackoverflow.com/questions/59645685/calling-a-class-defined-function-from-a-dll-file-c?noredirect=1#comment105473974_59645685 I've already been using DLL exports but would extern C in the class definition and function declarations be compatible? – Sahil Bora Jan 09 '20 at 20:59
  • No. C doesn't have classes, and exporting classes (`extern C`'ed or otherwise) is simply not portable between compilers from different vendors. The class methods you want to call will have to be wrapped inside of flat functions – Remy Lebeau Jan 09 '20 at 21:13
  • The function of "ResponseCode RunSample()" wouldnt exactlyt work to be a flat function as ResponseCode is a class – Sahil Bora Jan 09 '20 at 21:19
  • You would need to write a new DLL in Visual Studio that exports a flat, C-compatible function which then calls `RunSample()` and uses the `ResponseCode` as needed. You wouldn't expose the `ResponseCode` itself to the caller of the function. IOW, I wasn't suggesting you export `RunSample()` itself as a C function, you would USE IT INSIDE such a function instead. Of course, there is a simpler solution - forget using Amazon's AWS SDK altogether and just use Amazon's REST APIs instead, then you can use whatever HTTP library you want that is compatible with C++Builder, there are plenty available – Remy Lebeau Jan 09 '20 at 21:21
  • What if I was able to use the Amazon AWS Embedded C Version instead? – Sahil Bora Jan 09 '20 at 22:21
  • Might work, provided you have the C source files and can compile them directly in C++Builder – Remy Lebeau Jan 09 '20 at 22:41

0 Answers0