草庐IT

c# - 将具有非托管导出的 C# DLL 加载到 Python 中

coder 2023-08-24 原文

我使用 NuGet 包构建了一个 C# DLL (MyTestDll) UnmanagedExports :

[DllExport("Test", CallingConvention = CallingConvention.Cdecl)]
public static string Test(string name)
{
    return "hi " + name + "!";
}

我通过 ctypes DLL 导入从 Python 使用它:

path = "C:\\Temp\\Test"
os.chdir(path)
dll = ctypes.WinDLL("MyTestDll.dll")
f = dll.Test
f.restype = ctypes.c_char_p
print f('qqq')

这只是一个幻想,它确实有效。

然后,我又添加了一个 DLL (NoSenseDll):

namespace NoSenseDll
{
    public class NoSenseClass
    {
        public static int Sum(int a, int b)
        {
            return a + b;
        }
    }
}

我开始使用这个NoSenseDll来实现MyTestDll:

[DllExport("Test", CallingConvention = CallingConvention.Cdecl)]
public static string Test(string name)
{
    return NoSenseDll.NoSenseClass.Sum(4, 5).ToString();
}

不幸的是,它不起作用。 Python 说:

WindowsError: [Error -532462766] Windows Error 0xE043435

我尝试将 C:\\Temp\\Test 添加到路径中,但这没有帮助。


我写了一个 C++ 测试:

#include "stdafx.h"
#include "windows.h"
#include <iostream>
#include <string>
#include "WinBase.h"

typedef char*(__stdcall *f_funci)(const char*);

int _tmain(int argc, _TCHAR* argv[])
{
    int t;
    std::string s = "C:\\Temp\\Test\\MyTestDll.dll";
    HINSTANCE hGetProcIDDLL = LoadLibrary(std::wstring(s.begin(), s.end()).c_str());

    f_funci funci = (f_funci)GetProcAddress(hGetProcIDDLL, "Test");

    std::cout << "funci() returned " << funci(std::string("qqq").c_str()) << std::endl;
    std::cin >> t;
    return EXIT_SUCCESS;
}

如果第二个 DLL (NoSenseDll) 与 C++ 可执行文件位于同一文件夹中,则它会起作用。如果我只是将 NoSenseDll 文件夹添加到 PATH,它不起作用。

最佳答案

解决方案草案:

  1. 将 NoSenseDll 复制到 Python 的文件夹,在我的例子中是 %HOMEPATH%\Anaconda
  2. 重新启动 IPython/Spyder。

最终解决方案:

static MyTestDllClass() // static constructor
{
    AppDomain currentDomain = AppDomain.CurrentDomain;
    currentDomain.AssemblyResolve += new ResolveEventHandler(LoadFromSameFolder);
}
static Assembly LoadFromSameFolder(object sender, ResolveEventArgs args)
{
    string folderPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
    string assemblyPath = Path.Combine(folderPath, new AssemblyName(args.Name).Name + ".dll");
    if (File.Exists(assemblyPath) == false) return null;
    Assembly assembly = Assembly.LoadFrom(assemblyPath);
    return assembly;
}

最后的说明:

如果您因为 matplotlib 或 pandas 而无法使用 IronPython,
如果你因为 IPython 或 spyder 而不能使用 python.net,
如果您只是因为不想使用 COM Interop,
如果您真的想让 C# 和 Python 一起工作,请使用上面的解决方案和 C# 反射。

关于c# - 将具有非托管导出的 C# DLL 加载到 Python 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33175033/

有关c# - 将具有非托管导出的 C# DLL 加载到 Python 中的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  3. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  4. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  5. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  6. ruby-on-rails - 使用 config.threadsafe 时从 lib/加载模块/类的正确方法是什么!选项? - 2

    我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co

  7. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  8. ruby-on-rails - Rails 3.1 中具有相同形式的多个模型? - 2

    我正在使用Rails3.1并在一个论坛上工作。我有一个名为Topic的模型,每个模型都有许多Post。当用户创建新主题时,他们也应该创建第一个Post。但是,我不确定如何以相同的形式执行此操作。这是我的代码:classTopic:destroyaccepts_nested_attributes_for:postsvalidates_presence_of:titleendclassPost...但这似乎不起作用。有什么想法吗?谢谢! 最佳答案 @Pablo的回答似乎有你需要的一切。但更具体地说...首先改变你View中的这一行对此#

  9. Python 相当于 Perl/Ruby ||= - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。

  10. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

随机推荐