- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我用c写了一个dll库,用vs2017 64位编译,用python3.6 64位加载试试。但是,对象的成员变量地址被截断为 32 位。
这是我的 sim.c 文件,它被编译为 sim.dll:
class Detector {
public:
Detector();
void process(int* pin, int* pout, int n);
private:
int member_var;
};
Detector::Detector()
{
memset(&member_var, 0, sizeof(member_var));
myfile.open("addr_debug.txt");
myfile << "member_var init address: " << &member_var << endl;
}
void Detector::process(int* pin, int* pout, int n);
{
myfile << "member_var process address: " << &member_var << endl;
myfile.close();
}
#define DllExport __declspec( dllexport )
extern "C" {
DllExport Detector* Detector_new() { return new Detector(); }
DllExport void Detector_process(Detector* det, int* pin, int* pout, int n)
{
det->process(pin, pout, n);
}
}
这是我的 python 脚本:
from ctypes import cdll
lib = cdll.LoadLibrary(r'sim.dll')
class Detector(object):
def __init__(self):
self.obj = lib.Detector_new()
def process(self,pin, pout, n):
lib.Detector_process(self.obj,pin, pout, n)
detector = Detector()
n = 1024
a = np.arange(n, dtype=np.uint32)
b = np.zeros(n, dtype=np.int32)
aptr = a.ctypes.data_as(ctypes.POINTER(ctypes.c_int))
bptr = b.ctypes.data_as(ctypes.POINTER(ctypes.c_int))
detector.process(aptr, bptr, n)
这里是 addr_debug.txt 中 member_var 的地址:
member_var init address: 0000025259E123C4
member_var process address: 0000000059E123C4
因此访问它会触发内存访问错误:
OSError: exception: access violation reading 0000000059E123C4
我试图理解这个问题的一些尝试:
最佳答案
始终(正确地)为 C 中定义的函数指定 argtypes 和 restype,否则( C89 风格)它们将默认为 int(通常是 32bit),生成 !!!未定义的行为 !!!。在 64 位 上,地址(大于 2 GiB)将被截断(这正是您遇到的情况)。检查[SO]: C function called from Python via ctypes returns incorrect value (@CristiFati's answer)了解更多详情。
此外,遇到问题时,不要忘记 [Python.Docs]: ctypes - A foreign function library for Python .
下面是您的代码的改编版本。
检测器.cpp:
#include <stdio.h>
#include <memory.h>
#include <fstream>
#define SIM_EXPORT __declspec(dllexport)
#define C_TAG "From C"
#define PRINT_MSG_3SPI(ARG0, ARG1, ARG2) printf("%s - [%s] (%d) - [%s]: %s: 0x%0p(%d)\n", C_TAG, __FILE__, __LINE__, __FUNCTION__, ARG0, ARG1, ARG2)
using std::endl;
std::ofstream outFile;
class Detector {
public:
Detector();
void process(int *pIn, int *pOut, int n);
private:
int m_var;
};
Detector::Detector()
: m_var(25) {
outFile.open("addr_debug.txt");
outFile << "m_var init address: " << &m_var << endl;
PRINT_MSG_3SPI("&m_var(m_var)", &m_var, m_var);
}
void Detector::process(int *pIn, int *pOut, int n)
{
outFile << "m_var process address: " << &m_var << endl;
outFile.close();
PRINT_MSG_3SPI("&m_var(m_var)", &m_var, m_var);
}
#if defined(__cplusplus)
extern "C" {
#endif
SIM_EXPORT Detector* DetectorNew() { return new Detector(); }
SIM_EXPORT void DetectorProcess(Detector *pDet, int *pIn, int *pOut, int n)
{
pDet->process(pIn, pOut, n);
}
SIM_EXPORT void DetectorDelete(Detector *pDet) { delete pDet; }
#if defined(__cplusplus)
}
#endif
code00.py:
#!/usr/bin/env python
import ctypes as ct
import sys
import numpy as np
IntPtr = ct.POINTER(ct.c_int)
sim_dll = ct.CDLL("./sim.dll")
detector_new_func = sim_dll.DetectorNew
detector_new_func.argtypes = ()
detector_new_func.restype = ct.c_void_p
detector_process_func = sim_dll.DetectorProcess
detector_process_func.argtypes = (ct.c_void_p, IntPtr, IntPtr, ct.c_int)
detector_process_func.restype = None
detector_delete_func = sim_dll.DetectorDelete
detector_delete_func.argtypes = (ct.c_void_p,)
detector_delete_func.restype = None
class Detector():
def __init__(self):
self.obj = detector_new_func()
def process(self, pin, pout, n):
detector_process_func(self.obj, pin, pout, n)
def __del__(self):
detector_delete_func(self.obj)
def main(*argv):
detector = Detector()
n = 1024
a = np.arange(n, dtype=np.uint32)
b = np.zeros(n, dtype=np.int32)
aptr = a.ctypes.data_as(IntPtr)
bptr = b.ctypes.data_as(IntPtr)
detector.process(aptr, bptr, n)
if __name__ == "__main__":
print("Python {:s} {:03d}bit on {:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")),
64 if sys.maxsize > 0x100000000 else 32, sys.platform))
rc = main(*sys.argv[1:])
print("\nDone.")
sys.exit(rc)
注意事项:
正如我在开头所述,问题是 argtypes 和 restype 未指定(例如对于 DetectorNew:评论 detector_new_func.restype = ct.c_void_p
,又会遇到这个问题)
问题中的代码缺少部分(#includes, imports, ...),还有一些语法错误,所以它没有't 编译,因此不遵循 [SO]: How to create a Minimal, Complete, and Verifiable example (mcve)准则。请在询问时确保有MCVE
您分配的对象 (new Detector()
) 也必须被释放(否则会产生内存泄漏),所以我添加了从 (Python) Detector 的析构函数中调用的函数(DetectorDelete - 这样做)
其他(非关键)更改(标识符重命名、一些重构、打印到 stdout,...)
输出:
(py35x64_tes1) e:\Work\Dev\StackOverflow\q052268294>"c:\Install\x86\Microsoft\Visual Studio Community\2015\vc\vcvarsall.bat" x64
(py35x64_test) e:\Work\Dev\StackOverflow\q052268294>dir /b
code00.py
detector.cpp
(py35x64_test) e:\Work\Dev\StackOverflow\q052268294>cl /nologo /DDLL /EHsc detector.cpp /link /DLL /OUT:sim.dll
detector.cpp
Creating library sim.lib and object sim.exp
(py35x64_test) e:\Work\Dev\StackOverflow\q052268294>dir /b
code00.py
detector.cpp
detector.obj
sim.dll
sim.exp
sim.lib
(py35x64_test) e:\Work\Dev\StackOverflow\q052268294>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" ./code.py
Python 3.5.4 (v3.5.4:3f56838, Aug 8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)] 064bit on win32
From C - [detector.cpp] (28) - [Detector::Detector]: &m_var: 0x0000020CE366E270
From C - [detector.cpp] (34) - [Detector::process]: &m_var: 0x0000020CE366E270
Done.
关于Python ctypes cdll.LoadLibrary,实例化一个对象,执行其方法,私有(private)变量地址被截断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52268294/
我是 python 的新手。我试图找到我的文本的频率分布。这是代码, import nltk nltk.download() import os os.getcwd() text_file=open(
我对安卓 fragment 感到困惑。我知道内存 fragment 但无法理解什么是 android fragment 问题。虽然我发现很多定义,比如 Android fragmentation re
尝试对 WordPress 进行 dockerise 我发现了这个场景: 2个数据卷容器,一个用于数据库(bbdd),另一个用于wordpress文件(wordpress): sudo docker
这个问题已经有答案了: From the server is there a way to know that my page is being loaded in an Iframe (1 个回答)
我正在玩小型服务器,试图对运行在其上的服务进行docker化。为简化起见,假设我必须主要处理:Wordpress和另一项服务。 在Docker集线器上有许多用于Wordpress的图像,但是它们似乎都
我想要发生的是,当帐户成功创建后,提交的表单应该消失,并且应该出现一条消息(取决于注册的状态)。 如果成功,他们应该会看到一个简单的“谢谢。请检查您的电子邮件。” 如果不是,那么他们应该会看到一条适当
就是这样,我需要为客户添加一个唯一标识符。通过 strip 元数据。这就是我现在完全构建它的方式,但是我只有最后一部分告诉我用户购买了哪个包。 我试着看这里: Plans to stripe 代码在这
我有一个类将执行一些复杂的操作,涉及像这样的一些计算: public class ComplexAction { public void someAction(String parameter
这个问题已经有答案了: maven add a local classes directory to module's classpath (1 个回答) 已关闭10 年前。 我有一些不应更改的旧 E
我使用 fragment 已经有一段时间了,但我经常遇到一个让我烦恼的问题。 fragment 有时会相互吸引。现在,我设法为此隔离了一个用例,它是这样的: Add fragment A(也使用 ad
我的 html 中有一个 ol 列表,上面有行条纹。看起来行条纹是从数字后面开始的。有没有办法让行条纹从数字开始? 我已经包含了正在发生的事情的片段 h4:nth-child(even) {
如何仅使用 css 将附加图像 html 化? 如果用纯 css 做不到,那我怎么能至少用一个图像来做 最佳答案 这不是真正的问题,而是您希望我们为您编写代码。我建议您搜索“css breadcrum
以下是 Joshua 的 Effective Java 的摘录: If you do synchronize your class internally, you can use various te
在这里工作时,我们有一个框向业务合作伙伴提供 XML 提要。对我们的提要的请求是通过指定查询字符串参数和值来定制的。其中一些参数是必需的,但很多不是。 例如,我们要求所有请求都指定一个 GUID 来标
我有 3 个缓冲区,其中包含在 32 位处理器上运行的 R、G、B 位数据。 我需要按以下方式组合三个字节: R[0] = 0b r1r2r3r4r5r6r7r8 G[0] = 0b g1g2g3g4
我最近发现了关于如何使用 History.js、jQuery 和 ScrollTo 通过 HTML5 History API 对网站进行 Ajax 化的要点:https://github.com/br
我们有一个 Spring Boot 应用程序,由于集成需要,它变得越来越复杂——比如在你这样做之后发送一封电子邮件,或者在你之后广播一条 jms 消息等等。在寻找一些更高级别的抽象时,我遇到了 apa
我正在尝试首次实施Google Pay。我面临如何指定gateway和gatewayMarchantId的挑战。 我所拥有的是google console帐户,不知道在哪里可以找到此信息。 priva
昨天下午 3 点左右,我为两个想要从一个 Azure 帐户转移到另一个帐户的网站设置了 awverify 记录。到当天结束时,Azure 仍然不允许我添加域,所以我赌了一把,将域和 www 子域重新指
我正在使用terms facet在elasticsearch服务器中获取顶级terms。现在,我的标签"indian-government"不被视为一个标签。将其视为"indian" "governm
我是一名优秀的程序员,十分优秀!