Gromph
Gromph

Reputation: 163

Resolve a C (C++) call method from Python by using cppyy

In a C project, I would like to do the tests with the Python tools, so I integrated the Cling and Cppyy python package tool.

After that, I created a simple project like this. And found this help.

I have one source and one header.

header/pocket.h

#include <stdio.h>
void pocket(void);
int pocket_add(int op1, int op2);

source/pocket.c

#include <pocket.h>
void pocket(void)
{
  printf("Hello, pocket!\n");
}

int pocket_add(int op1, int op2)
{
  return op1 + op2;
}

I have this error on python interpreter

IncrementalExecutor::executeFunction: symbol '_Z6pocketv' unresolved while linking symbol '__cf_6'! You are probably missing the definition of pocket() Maybe you need to load the corresponding shared library? Error in : Failed to compile

Check the result via Python interpreter:

import cppyy
cppyy.include('include/pocket.h')
cppyy.load_library('build/libpocket.so')
cppyy.gbl.pocket()

IncrementalExecutor::executeFunction: symbol '_Z6pocketv' unresolved while linking symbol '__cf_6'! You are probably missing the definition of pocket() Maybe you need to load the corresponding shared library? Error in : Failed to compile

Source

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-security"
__attribute__((used)) extern "C" void __cf_6(void* obj, int nargs, void** args, void* ret)
{
    ((void (&)())pocket)();
    return;
}
#pragma clang diagnostic pop

Thanks

Upvotes: 1

Views: 668

Answers (1)

Wim Lavrijsen
Wim Lavrijsen

Reputation: 3788

cppyy assumes C++, i.e. name mangling will be applied. To make sure the declarations in your project's header files can be used both from C and C++, add extern "C" when used from C++. Like so:

#include <stdio.h>

#ifdef __cplusplus
extern "C" {
#endif

void pocket(void);
int pocket_add(int op1, int op2);

#ifdef __cplusplus
}
#endif

This will also be generally helpful for anyone using your code from C++, so it's not just for Python/cppyy.

Edit: forgot to add that you can also use "cppyy.c_include" instead of "cppyy.include" for C headers.

Upvotes: 1

Related Questions