无法找到通过C语言构建的Cython的函数

23c0lvtd  于 2023-04-19  发布在  其他
关注(0)|答案(1)|浏览(120)

我有一个Cython项目,包含以下模块:
CythonModule.pyx:

cdef int CPyFuncSwo():
    print("Do some stuff in cython")
    return 0

def PyFuncSwo()
    CPyFuncSwo()
    print("Do some stuff but in pure python only")

CythonModule.pxd:

cdef int CPyFuncSwo()

Setup.py:

from distutils.core import setup, Extension
from Cython.Build import cythonize

ext_modules = [
    Extension(
        "CythonModule",
        sources=["CythonModule.pyx",],
    ),
]

setup(
    name="CythonModule",
    ext_modules=cythonize(ext_modules),
    compiler_directives={'language_level': 3, "unraisable_tracebacks": True}
)

run.py:

import os
import sys
from CythonModule import PyFuncSwo
sys.path.insert(0, os.path.abspath("."))

if __name__ == '__main__':
    PyFuncSwo()

这工作得很好,当我运行python setup.py build_ext --inplace && python run.py时,代码编译并运行,同时也给了我一个新的CythonModule.cp39-win_amd64.pyd文件。现在我需要在纯C/C++代码中从.pyd模块调用PyFuncSwo()。在网上冲浪时,我遇到了下面的例子:
RunCythonInC.c:

#include <windows.h>
#include <stdio.h>

typedef (add_proc)(int a, int b);
int main(){
    add_proc *add;
    HANDLE h_dll;
    int a = 1, b = 2, c;
    h_dll = LoadLibrary("CythonModule.cp39-win_amd64.pyd");
    if(h_dll)
      {
        add = GetProcAddress(h_dll, "PyFuncSwo");
        if(add)
        {
          c = add(a, b); /*Explicit Call*/
        }
        else
        {
          printf("PyFuncSwo not found in CythonModule.cp39-win_amd64.pyd");
        }
        FreeLibrary(h_dll);
      }
      else
      {
        printf("Unable to load CythonModule.cp39-win_amd64.pyd");
        exit(-1);
      }
    return 0;
}

使用gcc将此代码编译为gcc -g RunCythonInC.c -o RunCythonInC.exe编译时会出现以下警告,但当我运行RunCythonInC.exe时,总是得到PyFuncSwo not found in CythonModule.cp39-win_amd64.pyd
我还将GetProcAddress(h_dll, "PyFuncSwo")更改为GetProcAddress(h_dll, "CPyFuncSwo"),但仍然得到相同的错误。我尝试的其他事情是使用_ as GetProcAddress(h_dll, "_PyFuncSwo")调用cython函数,但仍然得到相同的结果。有人能告诉我,如何在纯C代码中从.pyd模块调用cython函数?

hc2pp10m

hc2pp10m1#

您的直接问题是符号可见性。函数需要是cdef public,可能是need manually exporting on Windows

然而

你正在尝试做的是错误的,不太可能工作。

Cython不创建独立的C函数。相反,它生成Python模块。Cython函数有两个重要的先决条件:

  1. Python解释器正在运行。
  2. Cython模块的模块导入函数 * 必须 * 已被调用。
    如果不满足这些先决条件,函数很可能会以意想不到和令人困惑的方式崩溃。
    从C调用Cython函数的正确方法在Cython文档中介绍,不涉及GetProcAddress

相关问题