0

I am trying to call a C++ class DLL in python and it does not seem to work.

Here is my code :

// simple_lib.cpp : Defines the exported functions for the DLL.
#include "pch.h" // use pch.h in Visual Studio 2019
#include "simple_lib.h"
#include <iostream>


simplelib::simplelib()
{
}

simplelib::~simplelib()
{

}

int simplelib::add(int a, int b)
{
    return a + b;
}

int simplelib::sub(int a, int b)
{
    return a - b;
}

void simplelib::show() {
    std::cout << "simple display" << std::endl;
}
// simple_lib.h - Contains declarations
#pragma once

#ifdef SIMPLE_EXPORTS
#define SIMPLE_API __declspec(dllexport)
#else
#define SIMPLE_API __declspec(dllimport)
#endif

extern "C" {
    class simplelib {

    public:
        SIMPLE_API simplelib();
        SIMPLE_API ~simplelib();
        SIMPLE_API int add(int a, int b);

        SIMPLE_API int sub(int a, int b);

        SIMPLE_API void show();

    };
}

The DLL is successfully generated but then when I try to use in Python the add function for instance I get the following error.

Python 3.7.9 (tags/v3.7.9:13c94747c7, Aug 17 2020, 18:58:18) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from ctypes import *
>>> mylib = WinDLL("simple_lib.dll")
>>>print(mylib)
<WinDLL 'simple_lib.dll', handle 7ff835120000 at 0x219ece2b348>
>>> mylib.simplelib().add(3,4)

AttributeError: function 'simplelib' not found

Besides I have tried to use these functions without creating a class this way :

// simple_lib.cpp : Defines the exported functions for the DLL.
#include "pch.h" // use pch.h in Visual Studio 2019
#include "simple_lib.h"
#include <iostream>

int add(int a, int b)
{
    return a + b;
}

int sub(int a, int b)
{
    return a - b;
}

void show() {
    std::cout << "simple display" << std::endl;
}
// simple_lib.h - Contains declarations

#ifdef SIMPLE_EXPORTS
#define SIMPLE_API __declspec(dllexport)
#else
#define SIMPLE_API __declspec(dllimport)
#endif

extern "C" SIMPLE_API int add(int a, int b);

extern "C" SIMPLE_API int sub(int a, int b);

extern "C" SIMPLE_API void show();

And here if I try to use the add function(), it works perfectly

Python 3.7.9 (tags/v3.7.9:13c94747c7, Aug 17 2020, 18:58:18) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from ctypes import *
>>> mylib.add(3,4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'mylib' is not defined
>>> mylib = WinDLL("simple_lib.dll")
>>> mylib.add(3,4)
7

My config : Windows 10 64Bits, Visual Studio 2019.

So can you please help me on why it is not working when I am using a C++ class ?

Thanks in advance

Developer
  • 11
  • 1
  • 1
    Does this answer your question? [How to export a C++ class from a dll?](https://stackoverflow.com/questions/6840576/how-to-export-a-c-class-from-a-dll) – Maurice Meyer Jul 23 '21 at 13:03
  • Two points from [A: What is the effect of extern “C” in C++?](https://stackoverflow.com/a/1041880) are relevant. **1)** `extern "C"` is ignored for class members. **2)** Linkage to objects defined in C++ from other languages is implementation-defined and language-dependent. – JaMiT Jul 23 '21 at 13:13
  • You need to use `__stdcall` when using `WinDLL` otherwise you need to use `CDLL` which uses `cdecl`. Not sure how python will handle a 64-bit dll with `WinDLL` since there is no `stdcall` convention in 64-bit code. Also make sure the path to your dll is correct. – Brandon Jul 23 '21 at 13:49
  • Thanks for your answers but I still have the problem whether I use WinDLL or CDLL I can call the extern fonction but not those that are in the class. Besides I have noticed that the functions that are in the class are "name mangled" but not the extern ones. It might explain the issue but still I don't know how to fix it – Developer Jul 25 '21 at 19:28
  • I seem to have solved the issue. When VS generates the DLL, it gives name like that to each function ??0simplelib@@QEAA@XZ. That's why it does not find it in Python. I have fixed it using a pragma instruction "#pragma comment(linker, "/EXPORT:simplelib=??0simplelib@@QEAA@XZ"), that way the name of the class is found and named simplelib. – Developer Jul 26 '21 at 15:47

0 Answers0