我正在使用 pybind11 讓 python 呼叫現有的 C 模塊(庫)。但是,在 C 庫中,通過呼叫 ::GetModuleFileName (Visual Studio) 來確定已加載模塊的物理路徑,因為它在 C 中運行。但是當我通過pybind11從python(Jupyter Notebook)呼叫庫時,回傳的是python.exe的物理路徑。如何配置或更改以確保獲取 C 庫的物理路徑?
C 代碼是這樣的:Lib.h
#pragma once
void run();
庫檔案
#include <fstream>
#include <stdexcept>
#include <windows.h>
#include "libloaderapi.h"
#include "Lib.h"
void run()
{
char buf[1024];
::GetModuleFileName(0, buf, sizeof(buf));
std::ofstream of;
of.open("logging.txt");
if (!of.is_open()) {
throw std::runtime_error("Cannot open logging.txt");
}
of << "The loaded module is " << buf << std::endl;
}
pybind11 介面代碼:Direct.cpp
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <pybind11/stl.h>
#include "Lib.h"
namespace py = pybind11;
// wrap c function
void wrapper() {
run();
}
PYBIND11_MODULE(run_app, m) {
// optional module docstring
m.doc() = "pybind11 plugin";
m.def("run", &wrapper, "Run C Application");
}
pybind11 安裝檔案:setup.py
#from distutils.core import setup, Extension
#from distutils import sysconfig
from setuptools import setup, Extension
import pybind11
# The following is for GCC compiler only.
#cpp_args = ['-std=c 11', '-stdlib=libc ', '-mmacosx-version-min=10.7']
cpp_args = []
sfc_module = Extension(
'run_app',
sources=['Direct.cpp',
'Lib.cpp'],
include_dirs=[pybind11.get_include(), '.'],
language='c ',
extra_compile_args=cpp_args,
)
setup(
name='run_app',
version='1.0',
description='Python package with RunApp C extension (PyBind11)',
ext_modules=[sfc_module],
)
構建:
python setup.py 構建
呼叫這個庫的python代碼:py_run_app.py
import os
import sys
sys.path.append(os.path.realpath('build\lib.win-amd64-3.7'))
from run_app import run
run()
運行后:
python py_run_app.py
在 logging.txt 中加載的模塊是 C:....\python.exe
我想看到的是模塊的物理位置。
uj5u.com熱心網友回復:
Windows 術語中的“模塊”是 DLL 或加載為行程一部分的可執行檔案。每個模塊都有一個模塊句柄;按照慣例,特殊句柄NULL表示用于創建行程的可執行檔案。
GetModuleFileName需要模塊句柄作為第一個引數。你通過0,你會得到帶有特殊句柄的模塊的名稱,即可NULL執行檔案。這是完全可以預料的。
為了獲得 DLL 的檔案名,您需要找出它的句柄是什么。可以找到當前模塊的句柄:
HMODULE handle;
static char local;
bool ok = GetModuleHandleEx (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
(LPCSTR)&local,
&handle);
local可以是當前模塊中的任何函式或靜態/外部變數。參考。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/383738.html
