我可以显式关闭ctypes CDLL吗? [英] Can I explicitly close a ctypes CDLL?

查看:77
本文介绍了我可以显式关闭ctypes CDLL吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用于与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?

推荐答案

您需要关闭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
>>> 

这篇关于我可以显式关闭ctypes CDLL吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆