skywind3000 / PyStand

:rocket: Python Standalone Deploy Environment !!
MIT License
641 stars 75 forks source link

理论上有没有可能将这个项目编译为动态链接库(dll) #55

Closed JiaPai12138 closed 10 months ago

JiaPai12138 commented 10 months ago

rt

主要需求是在给另一个程序写dll形式的插件,同时想在同一进程不同线程额外运行一些py代码

JiaPai12138 commented 10 months ago

目前遇到的问题是环境加载都完成了 但是_Py_Main((int)_py_args.size(), &_py_args[0])返回1

测试用的脚本就一行 print(12345)

以下是线程部分代码

static DWORD CALLBACK some_thread(struct some *product) {
    Sleep(3000);

    HMODULE hModule = GetModuleHandle(L"some_product.dll");
    WCHAR dllPath[MAX_PATH];
    DWORD length = GetModuleFileNameW(hModule, dllPath, MAX_PATH);
    const wchar_t *lastBackslash = wcsrchr(dllPath, L'\\');
    long long int position = lastBackslash - dllPath;
    wcsncpy_s(product->workPath, sizeof(product->workPath) / sizeof(wchar_t),
              dllPath, position);

    AllocConsole();
    AttachConsole(ATTACH_PARENT_PROCESS);

    freopen("CONIN$", "r", stdin);
    freopen("CONOUT$", "w", stdout);

    std::cout << "This is a console window for a non-console program." << std::endl;

    PyStand ps(skCrypt("runtime"));
    system(skCrypt("set PYTHONIOENCODING=utf8"));
    if (ps.DetectScript() != 0) {
        return 3;
    }

    int fd = _fileno(stdout);
    if (fd >= 0) {
        std::string fn = std::to_string(fd);
        SetEnvironmentVariableA(skCrypt("PYSTAND_STDOUT"), fn.c_str());
    }
    fd = _fileno(stdin);
    if (fd >= 0) {
        std::string fn = std::to_string(fd);
        SetEnvironmentVariableA(skCrypt("PYSTAND_STDIN"), fn.c_str());
    }

    int hr = ps.RunString(init_script.c_str());
    std::cout << "Final " << GetLastError() << hr << std::endl;

    FreeConsole();
    return 0;
}

两处std::out都成功打印 PyStand其余部分代码都相同

JiaPai12138 commented 10 months ago

发现原因

"PYSTAND = os.environ['PYSTAND']\n"
Traceback (most recent call last):
  File "<string>", line 10, in <module>
  File "os.py", line 680, in __getitem__
KeyError: 'PYSTAND'

而在cpp代码中

SetEnvironmentVariableW(skCrypt(L"PYSTAND"), _pystand.c_str());

返回的是代表成功的非零值