我们有一个供应商,提供访问其硬件的库.不幸的是,如果您有多个设备,则需要多次导入其库,并使用不同的dll名称.因此,我们有一吨重复的代码,我担心它很快就会成为维护的噩梦.
我们现在所拥有的是:
namespace MyNamespace {
public static class Device01 {
public const string DLL_NAME = @"Device01.dll";
[DllImport(DLL_NAME, EntryPoint = "_function1")]
public static extern int Function1(byte[] param);
Run Code Online (Sandbox Code Playgroud)
...
[DllImport(DLL_NAME, EntryPoint = "_function99")]
public static extern int Function99(int param);
}
Run Code Online (Sandbox Code Playgroud)
....
public static class Device16 {
public const string DLL_NAME = @"Device16.dll";
[DllImport(DLL_NAME, EntryPoint = "_function1")]
public static extern int Function1(byte[] param);
Run Code Online (Sandbox Code Playgroud)
...
[DllImport(DLL_NAME, EntryPoint = "_function99")]
public static extern int Function99(int param);
}
}
Run Code Online (Sandbox Code Playgroud)
如果我使用的是C或C++,我只会在静态类中定义一个文件和#include它们多次,不是很好但是比替代方案好,但在C#中我没有那个选项.
如果有人对如何有效地定义工厂有任何聪明的想法,这将允许我们生成尽可能多的静态设备类,我会非常感兴趣.
谢谢,
编辑:函数原型是非常多变的,所以任何依赖它们的方法都是不合适的.感谢到目前为止的建议,我并没有如此迅速地阐述这么多想法.
我正在编写一个C#app,它在C++ API中调用了一些函数.我将C++代码构建到DLL中,C#代码使用DllImport调用API.(我使用.DEF文件作为C++ DLL,因此我不需要extern"C".)
到目前为止,API有一个功能,目前绝对没有任何功能:
bool Foo()
{
return false;
}
Run Code Online (Sandbox Code Playgroud)
在C#中,我有以下内容:
public class FooAPI
{
[DllImport("Foo.dll")]
public static extern bool Foo();
}
...
bool b = FooAPI.Foo();
if (!b)
{
// Throw an exception
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,由于某种原因,b总是评估为TRUE.我在if(!b)上有一个断点,调试器将其报告为'true',与C++函数返回的内容无关.
C#bool和C++ bool一样吗?虽然事实并非如此,但我仍然不知道如何找到返回值为'true':)
任何人都可以帮我解决这个奇怪的差异吗?
提前致谢!
我见过几个这样的例子:
[DllImport("user32.dll")]
static extern bool TranslateMessage([In] ref Message lpMsg);
[DllImport("user32.dll")]
static extern IntPtr DispatchMessage([In] ref Message lpmsg);
Run Code Online (Sandbox Code Playgroud)
但是,我不明白的是为什么有人会这样做只是像引用其他库一样引用DLL?MSDN声明:"在托管应用程序中重用现有的非托管代码时,DllImport属性非常有用.例如,托管应用程序可能需要调用非托管WIN32 API." 但是,那是说引用一个非托管的dll或者不可能引用它是没用的吗?
早上好,
我正在编写一个拼写检查程序,对于这种情况,它是性能关键的.既然如此,由于我打算连接到数据库并使用C#创建GUI,我在C中编写了一个编辑距离计算例程,并编译为我在C#中使用的DLL DllImport.问题是,我认为(虽然我可能是错误的),其编组字一个一个从String到char *导致大量的开销.就是这样,我考虑使用C++/CLI以便我可以String直接使用.NET中的类型...我的问题是,C++/CLI性能如何与用于繁重数学计算和数组访问的本机C代码相比较?
非常感谢你.
我需要以编程方式处理另一个Windows应用程序,搜索谷歌我找到了一个使用DLLImport属性处理Windows计算器的示例,并在C#中将user32.dll函数导入托管应用程序.
应用程序正在运行,我正在获取主窗口的句柄,即计算器本身,但后续代码不起作用.FindWindowEx方法不返回计算器子项的句柄,如按钮和文本框.
我尝试在DLLImport上使用SetLastError = True,发现我收到错误代码127,即"找不到过程".
这是我从中获取示例应用程序的链接:
http://www.codeproject.com/script/Articles/ArticleVersion.aspx?aid=14519&av=34503
如果有人知道如何解决它,请帮忙.
更新:DLLImport是:
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
Run Code Online (Sandbox Code Playgroud)
不起作用的守则是:
hwnd=FindWindow(null,"Calculator"); // This is working, I am getting handle of Calculator
// The following is not working, I am getting hwndChild=0 and err = 127
hwndChild = FindWindowEx((IntPtr)hwnd,IntPtr.Zero,"Button","1");
Int32 err = Marshal.GetLastWin32Error();
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用llvm-fs项目,该项目为F#提供llvm绑定.我已编译该LLVM-3.1.dll文件,--enable-shared它现在与我编译的可执行文件(我查看过Environment.CurrentDirectory)位于同一目录中.将DllImport在LLVM-FS是这样的:
[<DllImport(
"LLVM-3.1.dll",
EntryPoint="LLVMModuleCreateWithName",
CallingConvention=CallingConvention.Cdecl,
CharSet=CharSet.Ansi)>]
extern void* (* LLVMModuleRef *) moduleCreateWithNameNative(string ModuleID)
Run Code Online (Sandbox Code Playgroud)
然而,当我运行我的应用程序时,它出错:
Unable to load DLL 'LLVM-3.1.dll': The specified module could not be found.
(Exception from HRESULT: 0x8007007E)
Run Code Online (Sandbox Code Playgroud)
如何加载DLL?作为参考,这是我正在尝试加载的确切DLL.
我设计了一个C#Windows appln,它也在内部调用一些函数[通过DllImport()从C++ DLL导入]
我的C++代码在Win32平台中构建为.DLL,而我的C#构建为"任何CPU"平台.
当我在我的测试机器中运行.EXE(C#)时,我面临一个错误
尝试从hresult 0x8007000B加载具有不正确格式异常的程序
但是,如果我在我的机器中安装VSS 2010然后运行EXE,则不会遇到此错误.
1)出现此错误的原因?2)安装VSS时为什么没有观察到错误?
我使用Win7 OS(64位)在AnyCPU平台上构建.EXE(C#),而后者依赖于Win32内置的DLL(使用DllImport在C#中导入的C++ Dll)
我想知道它是如何DllImport工作的.我需要一个简单的英语解释 - 意思是简单的解释.
它是否与DLL中的导出方法静态链接,如"包含文件"指令/静态库?
或者当它到达C#程序中的执行点时,它是否从DLL动态调用该方法?
我看过几乎每一个例子,我可以通过谷歌找到,并不能完成任务的最简单的创建一个dll (窗口) 从nim
任何人都可以一步一步地解释它吗?
我正在使用nimIDE - aporia生成代码.
构建a是否dll需要使用命令行?我想有一个解决方法.
使用aporia IDE\ command line,如何通过编译下面的代码来实现与以下代码相同的结果dll:
extern "C" __declspec(dllexport) int __stdcall return_multiply(int num1, int num2)
{
return num1 * num2;
}
Run Code Online (Sandbox Code Playgroud)
您可能知道的代码可以从中调用 c#
我需要以下列形式将参数传递给不安全的DllImported函数:
[DllImport("third_party.dll")]
private static extern unsafe int start(int argc, char** argv);
Run Code Online (Sandbox Code Playgroud)
我假设它是一个字符串数组.但是,当我尝试执行以下操作时,我得到'无法从字符串[]转换为char**'错误.我如何让这个工作?谢谢.
string[] argv = new string[] { };
start(0, argv);
Run Code Online (Sandbox Code Playgroud)
编辑1: 问题被标记为重复,但看着可能重复的问题,我仍然没有看到如何使这个工作.
编辑2:进一步确认问题和所需参数.它看起来像您的标准argc/argv参数(参数计数,然后是参数值).与启动ac程序的方式相同:int main(int argc, char** argv); 对于这个特殊问题,我根本不想传递任何参数(因此count为0).
编辑3: 我从第三方库供应商那里获得了更多信息.这里是:
编辑4:使用工作解决方案进行最终编辑(至少在我的情况下).我会把它作为答案,但不能,因为这个问题被标记为重复.这是一个帮助我最多的问题的链接.最后,dll函数需要一个指向带有ANSI字符串的缓冲区的指针数组. 所以我的最终方法(基于相关问题)如下.在内存中创建一个数组来保存指针,然后将每个字符串分配到内存中的其他位置,并在第一个指针数组中写入指向这些字符串的指针.此代码适用于生产:
[DllImport("third_party.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
private static extern int start(Int32 args, IntPtr argv);
public bool start(params string[] arguments)
{
int result;
if (arguments == null || arguments.Length == 0)
{
result = dll_system_startup(0, IntPtr.Zero);
}
else …Run Code Online (Sandbox Code Playgroud)