我需要将SglW32.dll导入我的解决方案。
但我明白了:
AccessViolation exeption:尝试读取或写入受保护的 记忆。这通常表明其他内存已损坏。
我不能只使用DllImport。在那种情况下,找不到dll。
这是完整的例子。
using System;
using System.Runtime.InteropServices;
namespace TestDllimport
{
class Program
{
static void Main(string[] args)
{
var a = new MyClass();
var result = a.getValue();
}
}
class FunctionLoader
{
[DllImport("Kernel32.dll")]
private static extern IntPtr LoadLibrary(string path);
[DllImport("Kernel32.dll")]
private static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
public static Delegate LoadFunction<T>(string dllPath, string functionName)
{
var hModule = LoadLibrary(dllPath);
var functionAddress = GetProcAddress(hModule, functionName);
return Marshal.GetDelegateForFunctionPointer(functionAddress, typeof(T));
}
}
public class MyClass
{
//Define your path to dll.
//Get dll from: http://www.sg-lock.com/download/sglw32_v2_28.zip
private const string DLL_Path = @"C:\Users\admin123\Desktop\MyDlls\SglW32.dll";
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate ulong SglAuthentA(IntPtr AuthentCode);
static MyClass()
{
sglAuthentA = (SglAuthentA)FunctionLoader.LoadFunction<SglAuthentA>(DLL_Path, "SglAuthentA");
}
static private SglAuthentA sglAuthentA;
unsafe public ulong getValue()
{
IntPtr d = new IntPtr(5);
var a1 = sglAuthentA(d); // Exception IS HERE !!!!!
return a1;
}
}
}
我正在使用load函数从任何路径获取dll。之后,我从所需功能中委托代表。在我的情况下,函数是SglAuthentA。 此解决方案与另一个DLL一起使用,但不适用于SglW32.dll。
必填dll:http://www.sg-lock.com/download/sglw32_v2_28.zip
手动:http://www.sg-lock.com/download/SG-Lock_Manual_Eng.pdf
来源1:https://stackoverflow.com/a/8836228/2451446
编辑:解决方案感谢 Hans Passant 回答和 ja72 评论
using System.Runtime.InteropServices;
namespace TestDllimport
{
class Program
{
static void Main(string[] args)
{
var testA = DllImportClass.SglAuthentA(new uint[] { 5, 6, 7 }, new uint[] { 5, 6, 7 }, new uint[] { 5, 6, 7 });
var testB = DllImportClass.SglAuthentB(new uint[] { 5, 6, 7 });
}
}
static class DllImportClass
{
[DllImport("SglW32.dll")]
public static extern uint SglAuthentA(uint[] AuthentCode0, uint[] AuthentCode1, uint[] AuthentCode2);
[DllImport("SglW32.dll")]
public static extern uint SglAuthentB(uint[] AuthentCode);
}
}
答案 0 :(得分:5)
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate ulong SglAuthentA(IntPtr AuthentCode);
委托声明不正确,与api函数签名不匹配。 C中的ULONG是C#中的uint
。 C中的ULONG *不明确,可以是ref uint
,也可以是uint[]
。由于您应该传递48字节的身份验证代码,因此您知道它是一个数组。修正:
private delegate uint SglAuthentA(uint[] authentCode);
请务必传递正确的身份验证码。它不是5,数组必须有12个元素。如果您没有,请致电制造商购买。
private const string DLL_Path = @"C:\Users\admin123\Desktop\MyDlls\SglW32.dll";
请注意,不是无法使用[DllImport]的解决方法。对路径进行硬编码是一个问题,该文件不会出现在用户计算机上的该目录中。 DLL本身没有任何阻止加载的依赖项,遇到麻烦的唯一合理原因是你忘记将DLL复制到适当的位置。只有一个这样的地方,与你的EXE目录相同。
以正确的方式解决此问题,使用Project&gt;添加现有项目&gt;选择DLL。在Solution Explorer窗口中选择添加的文件。在“属性”窗口中,将“复制到输出目录”设置更改为“#34;复制如果更新&#34;”。重建您的项目并注意您现在可以在项目的bin \ Debug目录中获取DLL。现在[DllImport]将起作用。
关于本手册的注意事项,它列出了Visual Basic中的代码示例。这通常是您通常用作学习如何使用api的指南。但是代码是不是 VB.NET代码,它是VB6代码。如果您在示例代码中看到Long
,则应使用uint
或int
代替。
非常草率,它对产品的质量提出了很大的问号。他们似乎根本不解决的其他问题是如何确保自己的代码安全。使用加密狗时非常重要。请注意,任何人都可以对您的身份验证代码进行反向工程。更糟糕的是,要反编译您的程序并删除身份验证检查。你需要使用混淆器。