首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >pybind11与GetModuleFileName的冲突

pybind11与GetModuleFileName的冲突
EN

Stack Overflow用户
提问于 2021-12-13 18:13:52
回答 1查看 115关注 0票数 0

我使用pybind11来让python调用现有的C++模块(库)。但是,连接是通过C++库中的::GetModuleFileName (Visual )调用的,以确定在C++中运行的加载模块的物理路径。但是,当我通过pybind11从python (木星笔记本)调用库时,python.exe的物理路径将被返回。如何配置或更改以确保获得C++库的物理路径?

C++代码如下所示: Lib.h

代码语言:javascript
运行
复制
#pragma once

void run();

Lib.cpp

代码语言:javascript
运行
复制
#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

代码语言:javascript
运行
复制
#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

代码语言:javascript
运行
复制
#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

代码语言:javascript
运行
复制
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

我想看到的是模块的物理位置。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-13 21:21:19

Windows术语中的“模块”是一个DLL或一个可执行文件,加载到一个进程中。每个模块都有一个模块句柄;按照约定,特殊句柄NULL表示用于创建流程的可执行文件。

GetModuleFileName需要模块句柄作为第一个参数。如果传递0,您将得到带有特殊句柄NULL的模块的名称,即可执行文件。这是完全可以预料到的。

为了获得DLL的文件名,您需要了解它的句柄是什么。您可以找到当前模块的句柄:

代码语言:javascript
运行
复制
HMODULE handle;
static char local;
bool ok = GetModuleHandleEx (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
                             (LPCSTR)&local,
                             &handle);

local可以是当前模块中的任何函数或静态/extern变量。参考

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70339167

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档