Wrapping a C++ DLL in C so I can use LoadLibrary

-1

I'm trying to wrap a C++ DLL (Paddle.dll) so that I can import its functions with LoadLibrary. I am doing this as I need to use it from a VST plugin, which is itself a DLL.

I've followed the example at Wrapping C++ class API for C consumption for wrapping the C++ class with C functions.

The wrapper DLL is being loaded successfully and I can call the initPaddle method to return the opaque object pointer.

The issue I am having is it crashes when first trying to call a method on the Paddle object. The error message is:

Exception thrown at 0x089B2D70 (Paddle.dll) in Plugin Host.exe: 0xC0000005: Access violation reading location 0x0000001E.

I don't know the reason for the crash. When debugging, I can see that the Paddle object has been instantiated, and it's internal d_ptr is non-null.

Is it possible to expose C++ class methods in a DLL as I'm trying to do?

(BTW I have had zero support from Paddle on this, after days of emails and support messages).

This is the wrapper header:

PaddleWrapper.h

#ifdef PADDLEWRAPPER_EXPORTS    // VS sets project name exports automatically
#define DECLSPEC    __declspec(dllexport)
#else
#define DECLSPEC    __declspec(dllimport)
#endif

typedef void PaddleWrapper;

#ifdef __cplusplus
extern "C" {
#endif

    DECLSPEC PaddleWrapper* initPaddle(const char* apiKey, const char* productId, const char* vendorId);
    DECLSPEC void startLicensing(const PaddleWrapper* paddleWrapper, const char* productName, const char* vendorName, float price, int trialLengthInDays,
        const char* productImage, bool timeTrialLicense);

#ifdef __cplusplus
}
#endif

And implementation:

PaddleWrapper.cpp

#include "PaddleWrapper.h"
#include "windows.h"
#include "paddle.h"

using namespace PaddleSDK;

extern "C" 
{

    PaddleWrapper* initPaddle(const char* apiKey, const char* productId, const char* vendorId) 
    {
        Paddle* paddle = Paddle::initSharedInstance(apiKey, productId, vendorId);

        return (PaddleWrapper*) paddle;
    }

    void startLicensing(const PaddleWrapper* paddleWrapper, const char* productName, const char* vendorName, float price, int trialLengthInDays,
        const char* productImage, bool timeTrialLicense)
    {
        Paddle* paddle = (Paddle*) paddleWrapper;

        // CRASHES HERE:
        paddle->setProductData(productName, vendorName, (double)price, trialLengthInDays, productImage);  
        paddle->startLicencing(timeTrialLicense);
    }
}

For reference, here is the supplied header file from Paddle:

paddle.h

#ifdef PADDLE_STATIC
    #define DECLSPEC    
#else
    #ifdef PADDLE_EXPORTS   // VS sets project name exports automatically
    #define DECLSPEC    __declspec(dllexport)
    #else
    #define DECLSPEC    __declspec(dllimport)
    #endif
#endif

#include<windows.h>

namespace PaddleSDK
{
    class DECLSPEC Paddle
    {
    private:
        // Singleton PaddleSDK for those that wish to use it (can init direct if they dont)
        static Paddle * singleton;

        const char * apiKey;
        const char * productId;
        const char * vendorId;

        struct PaddleSDKInternals;
        PaddleSDKInternals * d_ptr;

    public:
        // Initialises a shared singleton version of the Paddle SDK
        static Paddle * initSharedInstance(const char *apiKey, const char *productId, const char *vendorId);
        // Fetches a previously initialised singleton
        static Paddle * getSharedInstance();

        // Creates a new instance of the Paddle SDK for the given credentials
        Paddle(const char *apiKey, const char *productId, const char *vendorId);

        // Sets default product information for use on first run
        void setProductData(const char *productName, const char *developerName, double productPriceUSD, int trialLength, const char *imagePath);
        void setProductData(LPWSTR productName, LPWSTR developerName, double productPriceUSD, int trialLength, LPWSTR imagePath);

        // Called once per app start
        void startLicencing(bool timeTrial);

        // Returns true if the product has been activated successfully by your customer
        bool productActivated();

        // Deactivate the current licence
        bool deactivateLicence();

        // Returns number of days remaining on this users trial. If startLicencing has not been successful, or a user's trial has expired then this will return 0
        int getDaysRemainingOnTrial();

        // Gets the duration of this users trial in days. Will default to 0 days if startLicencing has not been successful
        int getTrialLength();

        // Used to show the licencing process to the user
        void showLicensingWindow();

        //Start the purchase process directly
        void startPurchase();

        //Override price (USD)
        void overridePrice(double price);

        //Allow continued use of app after end of trial
        void setContinueOnTrialEnd(bool trialContinue);

        //Get email and licence code used for activation
        LPCWSTR activatedEmail();
        LPCWSTR activatedLicence();
    };
}
c++
dll
dllimport
dllexport
asked on Stack Overflow Aug 10, 2018 by Adamski • edited Aug 10, 2018 by Adamski

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0