• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

我可以显式关闭ctypes CDLL吗

用户头像
it1352
帮助1

问题说明

我有一个用于与C库进行交互的Python 2.7 GUI。我在GUI中进行了一堆设置,然后按开始按钮。然后,我正在查看结果,不再需要库代码。但是我想在更改库时保留所有GUI状态。

I have a Python 2.7 GUI for interacting with a C library. I do a bunch of setup in the GUI, then I press "go" button. Then, I'm looking at results and no longer need the library code. But I would like to keep all the GUI state while changing the library.

我导入 so 或<$带有 ctypes 的c $ c> dll ,显然可以打开文件进行读取。但是,我想显式关闭文件以重新编译并覆盖它。然后,当我再次按执行按钮时,我想导入新版本。

I import the so or dll with ctypes, which obviously opens the file for reading. But, I'd like to explicitly close the file in order to recompile and overwrite it. Then, when I press the "go" button again, I'd like to import the new version.

在最坏的情况下,我可以将文件复制到 tempfile.NamedTemporaryFile ,但随后我可以打开数十个文件的句柄,无法清理。

In the worst case scenario, I could copy the file to a tempfile.NamedTemporaryFile, but then I have handles open to dozens of files, none of which I can clean up.

我可以以某种方式明确关闭文件句柄吗?或者,我可以将文件的内容读取到 StringIO 对象中,并以某种方式指向 ctypes 吗?

Can I somehow explicitly close the file handle? Or, can I read the contents of the file into a StringIO object and somehow point ctypes at that?

正确答案

#1

您需要关闭DLL的句柄,以便它首先发布,以便可以使用该文件,并且需要获取该文件的句柄。库,然后将其传递给在Windows上 FreeLibrary ,则可以使用DLL文件执行所需的操作:

You need to close the handle to the DLL so it released first so you can work with the file, you need to get the handle of the library and then pass it to FreeLibrary on Windows, then you can do what you need with the DLL file:

from ctypes import *

file = CDLL('file.dll')

# do stuff here

handle = file._handle # obtain the DLL handle

windll.kernel32.FreeLibrary(handle)

预览:

这是一个测试DLL:

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

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {

  switch( fdwReason ) {
    case DLL_PROCESS_ATTACH:
      puts("DLL loaded");
    break;

    case DLL_PROCESS_DETACH:
      puts("DLL unloaded");
    break;

    case DLL_THREAD_ATTACH:
    break;

    case DLL_THREAD_DETACH:
    break;
  }

  return TRUE;
}

__declspec(dllexport) void function(void) {
  puts("Hello");
}

预览:

>>> from ctypes import *
>>>
>>> file = CDLL('file.dll')
DLL loaded
>>>
>>> # now it's locked
...
>>> file.function()
Hello
0
>>> windll.kernel32.FreeLibrary(file._handle)
DLL unloaded
1
>>> # not it's unlocked

在Linux上,您使用 dlclose 将会是:

on Linux you use dlclose it would be:

from ctypes import *

file = CDLL('./file.so')

# do stuff here

handle = file._handle # obtain the SO handle

cdll.LoadLibrary('libdl.so').dlclose(handle)

这是一个相似的共享对象:

Here is a similar shared object:

#include <stdio.h>

__attribute__((constructor)) void dlentry(void) {
  puts("SO loaded");
}

void function(void) {
  puts("Hello");
}

__attribute__((destructor)) void dlexit(void) {
  puts("SO unloaded");
}

预览:

>>> from ctypes import *
>>> 
>>> file = CDLL('./file.so')
SO loaded
>>> 
>>> file.function()
Hello
6
>>> cdll.LoadLibrary('libdl.so').dlclose(file._handle)
SO unloaded
0
>>> 

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /reply/detail/tanhcfjgjb
系列文章
更多 icon
同类精品
更多 icon
继续加载