我在这方面花了超过48个小时,所以任何一种帮助/建议/暗示/批评都是非常感谢的!
我在网上阅读了大部分关于相关内容的文档,尽管我并不完全理解它们。通过调整代码的某些部分并再次编译,问题似乎是链接器无法解决dll头文件(*.h)中声明的外部函数。
知道我测试*.pyx和*.h之间的“连接”可能是有用的,因为如果在调用*.pyx中的api函数时设置较少的参数,错误消息会说参数的数量与标头中的参数不一致。因此,真正的问题是*.pyx和*.dll之间的交互,这应该依赖于*.lib。至少我是这么想的。
由于我不确定*pyx的*.h文件是否应该使用"__declspec(dllimport)“或"__declspec(dllexport)",所以我尝试了两者。他们两个都没有解决这个问题。
换句话说,链接器无法找到api函数(符号)的定义在*.dll中的位置,因为即使我在setup.py中更改了库参数(例如,从库= 'libcds‘到库=’which‘),错误msg也是相同的,即"LNK2019:函数blabla中引用的未解析的外部符号__imp_CalcUpfrontCharge_API .
因此,我怀疑安装文件缺少某些部分,以便让编译知道它应该查找*.lib文件并在dll中找到定义。现在,它似乎忽略了*.lib,因为正如我所说的,即使我完全在扩展名()中删除了库参数,我也得到了相同的错误。
我还试图从源代码构建pyd (不是dll),但也失败了。
it is as simple as this (updated CDS_API macro):
libcds.h
#ifdef CDS_EXPORTS
#define CDS_API __declspec(dllexport)
#else
#define CDS_API __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C"
{
#endif
CDS_API double CalcUpfrontCharge_API(
char *expiries[], double rates[], double couponRate, double
parSpread, double recoveryRate, char *today1, char *valueDate1, char
*effectDate1, char *maturity
);
#ifdef __cplusplus
}
#endif
cdspricer.pyx
# distutils: language = c++
# distutils: libraries = libcds
# distutils: include_dirs = .
# distutils: library_dirs = .
cimport numpy as np
from libc.stdlib cimport malloc, free
from libcpp.vector cimport vector
from libcpp.string cimport string
from libc.string cimport strcpy, strlen
cdef extern from "libcds.h":
double CalcUpfrontCharge_API(
char *expiries[], double rates[], double couponRate, double
parSpread, double recoveryRate, char *today1, char *valueDate1, char
*effectDate1, char *maturity);
def CalcUpfrontCharge(vector[char *] expiries,
vector[double] rates,
double couponRate,
double parSpread,
double recoveryRate,
string today,
string valueDate,
string effectDate,
string maturity
):
some logic...
cdef double res = CalcUpfrontCharge_API(c_expiries, c_rates, couponRate,
parSpread, recoveryRate, today1, valueDate1, effectDate1, maturity1)
return res
setup.py
import setuptools
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
import numpy as np
ext_modules = [
Extension('cdspricer',
['cdspricer.pyx'],
# Note here that the C++ language was specified
# The default language is C
language="c++",
depends = ['N:\Trading\Python\ISDA\libcds.lib'],
extra_link_args = [],
include_dirs=["N:\Trading\Python\ISDA"],
libraries=['libcds'],
library_dirs=["N:\Trading\Python\ISDA"])
]
setup(
name = 'cdspricer',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules,
extra_compile_args=["-O3", "-Wall"],
include_dirs=[np.get_include()]
)发布于 2019-06-15 20:10:52
好吧,我回来回答我自己的问题。
经过36个小时的努力,我终于在我的Windows7系统上工作了。由于使用C/C++ DLL进行Cython编译需要如此多的细节和技巧,其中任何一个细节和技巧都非常关键,以至于即使缺少一个看似微不足道的步骤也可能导致编译/链接过程的整个失败,因此我将强调我遇到的所有容易出错的缺陷和解决方案:
ext_modules = [
Extension('cdspricer',
['cdspricer.pyx'],
# Note here that the C++ language was specified
# The default language is C
language="c++",
extra_link_args = [],
include_dirs=["N:\Trading\Python\ISDA"],
libraries=['cdslib', 'msvcrt', 'msvcmrt'],
library_dirs=["N:\Trading\Python\ISDA"])
]
setup(
name = 'cdspricer',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules,
extra_compile_args=["-O3", "-Wall"],
include_dirs=[np.get_include()] # This gets all the required Numpy core files
)#ifdef CDSLIB_EXPORTS
#define CDSLIB_API __declspec(dllexport)
#else
#define CDSLIB_API __declspec(dllimport)
#endif
extern "C"
{
CDSLIB_API double CalcUpfrontCharge_API(
char *expiries[], double rates[], double couponRate, double parSpread, double
recoveryRate, char *today1, char *valueDate1, char *effectDate1, char *maturity
);
CDSLIB_API double Test(
double a
);
}在源代码中,您有:
CDSLIB_API double Test(double a)
{
double b;
b = a + 1;
return b;
}测试函数将工作,而CalcUpfrontCharge_API则不能.
发布于 2019-06-19 14:41:53
因此,我只是遇到这个问题,使用插件SDK向导,将创建一个插件外壳。它不会只使用shell构建,并且会得到此错误。这将是特定于这种类型的设置,但对我来说,修复是因为我收到了这样的警告:
warning C4335: Mac file format detected: please convert the source file to either DOS or UNIX format在以正确的格式保存文件后,未解决的外部符号错误消失,我可以构建解决方案。
虽然我知道,这可能不是解决你的情况,我希望这可以帮助某人寻找一个答案。
https://stackoverflow.com/questions/56605015
复制相似问题