Tag: pinvoke

为什么String.Equals(Object obj)检查这是否== null?

可能重复: 为什么检查这个!= null? // Determines whether two strings match. [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] public override bool Equals(Object obj) { //this is necessary to guard against reverse-pinvokes and //other callers who do not use the callvirt instruction if (this == null) throw new NullReferenceException(); String str = obj as String; if (str == null) return false; if (Object.ReferenceEquals(this, […]

FreeLibrary无限期地返回true

有没有理由说FreeLibrary会重复返回true? 我正试图从我的进程中卸载一些本机dll,所以我得到它的句柄,然后调用FreeLibrary直到引用计数变为零,因此FreeLibrary返回false …但它永远不会: IntPtr pDll = DllLoadingImports.LoadLibrary(dllTounLoad); //throw if pDll == IntPtr.Zero while(DllLoadingImports.FreeLibrary(pDll)); 代码运行,永不返回。 进程资源管理器也会显示仍然加载的dll。 更多背景: 我正在尝试卸载使用DllImport加载的本机库,我正在使用这里描述的技巧: https ://stackoverflow.com/a/2445558/2308106这是为了进行原型设计,所以我不必关心可能的结果…但我很困惑为什么图书馆不会卸载 编辑1 :我发现通过在GetModuleHandleEx函数中指定GET_MODULE_HANDLE_EX_FLAG_PIN标志可以实现类似的行为(可以在dll加载时从DllMain中调用)。 我试图卸载的DLL是python.dll(更准确地说是python36.dll)。 但是在python源代码中没有找到这个标志的用法。 DllMain本身是空的。 编辑2 :我被问到最小的可执行示例 – 所以这里它:它使用pythonnet库(版本2.3.0) – 这是PythonEngine调用。 [TestFixture] public class PythonUnloadTest { public static class DllImports { [DllImport(“kernel32.dll”)] public static extern IntPtr LoadLibrary(string dllToLoad); [DllImport(“kernel32.dll”)] public static extern bool FreeLibrary(IntPtr hModule); } […]

PInvoking C ++ DLL时出现AccessViolationException(cdecl调用约定问题?)

我整天都在研究这个问题,而且我并不聪明: 我有一个C#DLL,PInvokes C ++ DLL中的方法。 在调试模式下编译时我没有遇到任何问题,但在Release模式下编译时,我得到一个AccessViolationException。 谷歌搜索这个问题告诉我,它可能是不合规的调用约定的问题。 代码现在在C#中看起来像这样: [return: MarshalAs(UnmanagedType.U1)] [DllImport(“Native.dll”, CallingConvention = CallingConvention.Cdecl)] internal static extern Boolean AMethod(Int32 mode, byte frame); 在C ++中: extern “C” { DLL_EXPORT bool AMethod(int mode, BYTE frame) { … } } 我已经在VS2010中使用__cdecl调用约定设置了C ++项目,但我仍然得到了AccessViolationException,我不知道我还能做些什么。 我应该注意我的C ++ DLL使用第三方DLL,我不知道他们使用什么调用约定。 任何帮助,将不胜感激! 哦,我的开发机器上没有例外,只在我的目标系统上。

P / invoke函数将指针指向struct

诸如CreateProcess之类的函数具有指向结构的指针。 在CI中,只传递NULL作为可选参数的指针,而不是在堆栈上创建虚拟结构对象并将指针传递给虚拟对象。 在C#中,我已将其声明为(p / invoke) [DllImport(“kernel32.dll”, CharSet = CharSet.Auto)] public static extern bool CreateProcess( string lpApplicationName, string lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes, ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles, CreateProcessFlags dwProcessCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, ref PROCESS_INFORMATION lpProcessInformation); 但是,如果我尝试为lpProcessAttributes参数或lpThreadAttributes参数传递null , lpProcessAttributes出现编译器错误: 错误2参数3:无法从“”转换为“ref Debugging.Wrappers.SECURITY_ATTRIBUTES” 如何修改上面的函数签名,以便我可以为SECURITY_ATTRIBUTES参数传递null ,而不会出现此编译器错误? (如果我愿意,还能传递一个真正的结构?)

为PInvoke正确声明SP_DEVICE_INTERFACE_DETAIL_DATA

SP_DEVICE_INTERFACE_DETAIL_DATA结构: typedef struct _SP_DEVICE_INTERFACE_DETAIL_DATA { DWORD cbSize; TCHAR DevicePath[ANYSIZE_ARRAY]; } SP_DEVICE_INTERFACE_DETAIL_DATA, *PSP_DEVICE_INTERFACE_DETAIL_DATA; 如何在C#中声明它以使Marshal.SizeOf正常工作? 我没有分配动态缓冲区的问题。 我只想以适当的非硬编码方式计算cbSize 。 PInvoke.net的定义是错误的。 PInvoke.net的解释也是错误的: SP_DEVICE_INTERFACE_DETAIL_DATA didd = new SP_DEVICE_INTERFACE_DETAIL_DATA(); didd.cbSize = 4 + Marshal.SystemDefaultCharSize; // trust me 🙂 不要相信他。 4 + Marshal.SystemDefaultCharSize仅在x86上有效。 sizeof(int) + Marshal.SystemDefaultCharSize 。 在x64上,它失败了。 这是非托管C ++给出的: 86 结构尺寸A: 5 设备路径偏移A: 4 结构尺寸W: 6 设备路径W的偏移量: 4 64位 结构尺寸A: 8 […]

在另一个用户上下文中执行代码

我的应用程序带有需要以管理员身份运行的清单,但应用程序的一部分是使用WNetAddConnection2映射驱动器,我相信由于凭据等原因,它需要在普通用户上下文中运行。有没有办法执行此操作普通用户上下文中的一些代码,无需创建单独的进程。 编辑 从我的评论到目前为止,但它不起作用。 我预计它不会因为我真的不明白我应该如何使用它。 如果我打开一个新问题,也许最好? class Program { [DllImport(“advapi32.DLL”)] public static extern bool ImpersonateLoggedOnUser(IntPtr hToken); [DllImport(“advapi32.DLL”)] public static extern bool RevertToSelf(); static void Main(string[] args) { IntPtr phToken = IntPtr.Zero; ImpersonateLoggedOnUser(phToken); MapDrives(); RevertToSelf(); } } 编辑 如果当前用户具有管理员权限,那么主进程将使用清单提升,在提升的代码中我想在用户非提升空间中运行命令,因为这似乎具有不同的环境变量等。我相信曾经线程启动它不能改变自己,它需要运行一个新的。

与Windows7 Display API通信

我还没有找到一个体面的(任何真正的)pinvoke包装新win7 CCD api。 api可以从这里找到: http : //msdn.microsoft.com/en-us/library/windows/hardware/hh406259(v = vs.85).aspx 我花了几个小时来转换结构/方法调用,以便我可以在C#中使用它。 这是第一个“草案”: using System; using System.Runtime.InteropServices; namespace CONVERTING_CCD { /// /// This class takes care of wrapping “Connecting and Configuring Displays(CCD) Win32 API” /// Author Erti-Chris Eelmaa || easter199 at hotmail dot com /// public class CCDWrapper { [StructLayout(LayoutKind.Sequential)] public struct LUID { public uint LowPart; […]

p /调用从c#调用C dll

这是我的C代码 extern “C” { __declspec(dllexport) void DisplayHelloFromDLL(string a) { printf (“%s\n”,a) } } 这是我的C#代码 class HelloWorld { [DllImport(“TestLib.dll”)] public static extern void DisplayHelloFromDLL(string a); static void Main () { string a = “Hello”; DisplayHelloFromDLL(a); } } 它成功构建但崩溃如下: 调试http://sofzh.miximages.com/c%23/1qr9sj.jpg 那么,如何使用P / invoke从C#调用我自己的C dll? 请提前帮助。

.NET:如何使用C#中的STARTUPINFOEX调用CreateProcessAsUser()

Web上用于调用CreateProcessAsUser()的大多数示例代码都具有与以下类似的PInvoke签名: public static extern bool CreateProcessAsUser(IntPtr hToken, string lpApplicationName, string lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes, ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles, int creationFlags, IntPtr environment, string currentDirectory, ref STARTUPINFO startupInfo, out PROCESS_INFORMATION processInfo); 问题是,我想通过STARTUPINFOEX,这在Vista / W7中是允许的。 如果我正在编写C / C ++那么我就可以投出它。 我应该如何在C#中处理这个问题? STARTUPINFOEX看起来像这样: [StructLayout(LayoutKind.Sequential)] public struct STARTUPINFOEX { public STARTUPINFO StartupInfo; public IntPtr lpAttributeList; }; 我应该将IntPtr传递给结构吗? 如果我改变Pinvoke签名并做这样的事情…… IntPtr […]

C#调用C DLL,传递char *作为参数不正确

我在VS2012中用C#语言调用DLL(C写)。 mylib.dll是我要在C#中调用的本机dll,而mylib.dll也会调用另一个mylib_another.dll。 C函数声明为: extern DECLSPEC_DLL BOOLEAN_TYPE SetConnection(char *dev, char *addr); 在My C#文件中,我将其声明为: [DllImport(“C:\\mylib.dll”, EntryPoint = “SetConnection”, CharSet = CharSet.Auto)] public static unsafe extern int SetConnection(StringBuilder dev, StringBuilder addr); 当我在代码中调用它时,我发现字符串只传递了一个字符,当我将dev作为“USB”传递时,本机DLL实际上只获得了一个“U”。 如果我将声明改为: [DllImport(“C:\\mylib.dll”, EntryPoint = “SetConnection”, CharSet = CharSet.Ansi)] public static unsafe extern int SetConnection(StringBuilder dev, StringBuilder addr); 然后它将引发System.AccessViolationExceptionexception: System.Reflection.TargetInvocationException was unhandled HResult=-2146232828 Message=Exception has been thrown […]