7

Consider this file containing two similar functions:

#include <iostream>

int main()
{
  std::cout << "main\n";
}

int notmain()
{
  std::cout << "notmain\n";
}

I compiled this into a shared library:

g++ -shared -Wl,-soname,code -o code.so -fPIC code.cpp

I wish to call these from python, for main this works fine:

import ctypes
libc = ctypes.cdll.LoadLibrary("code.so")
libc.main()

Which prints main. However, notmain doesn't work:

import ctypes
libc = ctypes.cdll.LoadLibrary("code.so")
libc.notmain()

The output:

<ipython-input-63-d6bcf8b748de> in <module>()
----> 1 libc.notmain()

/usr/lib/python3.4/ctypes/__init__.py in __getattr__(self, name)
    362         if name.startswith('__') and name.endswith('__'):
    363             raise AttributeError(name)
--> 364         func = self.__getitem__(name)
    365         setattr(self, name, func)
    366         return func

/usr/lib/python3.4/ctypes/__init__.py in __getitem__(self, name_or_ordinal)
    367 
    368     def __getitem__(self, name_or_ordinal):
--> 369         func = self._FuncPtr((name_or_ordinal, self))
    370         if not isinstance(name_or_ordinal, int):
    371             func.__name__ = name_or_ordinal

I assume that main is 'exported' to the outside world (w.r.t. code.so) in a different way than notmain because main is a special case in the c++ specs. How can I 'export' notmain in the same way? Or: how can I fix the exception?

EDIT As suggested by @abdallahesam I added estern "C" to notmain, this did not change (or solve) the problem:

#include <iostream>

int main()
{
  std::cout << "main\n";
}

extern "C" {
  int notmain()
  {
std::cout << "notmain\n";
  }
}

CORRECTION

The suggestion did solve the problem, I just needed to restart the (i)python session. Apparently this matters :)

2
  • Interestingly, nm shows the main-function as a symbol 00000000000008a5 T main and the notmain-function as a symbol with 'signature additions' for the typing: 00000000000008c6 T _Z7notmainv Commented Dec 20, 2015 at 11:38
  • I was having the same problem and the only solution was restarting the python session. In my case I will need this to work without restarting the python session. Any clue? Commented Apr 28, 2016 at 1:31

2 Answers 2

6

I think you should add extern "C" to your notmain function header to prevent c++ compiler from altering function name.

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you, I tries this as denoted in the OP, but it didn't solve the problem.
Correction: I needed to restart my ipython session for this to work.
It doesn't matter whether you use extern "C" ... or extern "C" {...} if ... is just one statement. I tried both anyway, and it works.
Thank you anyway! This could have cost me hours to solve otherwise.
0

Another possible solution is to link all libraries dynamically to the one library you want to open by ctypes.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.