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();
};
}
User contributions licensed under CC BY-SA 3.0