标签: pinvoke

如何在C#中调用"CreateFile"?

在获得有关从存储设备检索.MBR的大量信息之后,结论是使用P/Invoke来调用CreateFile.

但是如何在C#中完成这项工作?请说明!对你的帮助表示感谢!!!

c# pinvoke

9
推荐指数
1
解决办法
2万
查看次数

如何将结构编组为指向结构的指针?

我试图将一个结构从C#传递到C++库.我将结构作为对象传递,C++函数将它作为指针(void*).

我有问题通过结构.

[DllImport("MockVadavLib.dll", CharSet = CharSet.Ansi)]
public static extern IntPtr TheFunction([MarshalAs(UnmanagedType.LPStruct)] UserRec userRec);
Run Code Online (Sandbox Code Playgroud)

这是我得到的运行时异常文本:

"无法封送'参数#1':无效的托管/非托管类型组合(此值类型必须与Struct配对)."

虽然我发现了一篇在这种情况下使用LPStruct的MSDN文章.

这是我试图编组的结构:

[StructLayout(LayoutKind.Sequential)]
public struct UserRec {
    [MarshalAs(UnmanagedType.I4)]
    public int userParam1;
}
Run Code Online (Sandbox Code Playgroud)

这是C++函数:

MOCKVADAVLIB_API tVDACQ_CallBackRec * TheFunction(void * userParams) {...
Run Code Online (Sandbox Code Playgroud)

c# pinvoke

9
推荐指数
2
解决办法
2万
查看次数

查找具有Process的特定文本的窗口

我试图找出一个具有特定功能的窗口是否已被进程打开.这个过程产生了多个窗口,我需要检查它们.

我毫不费力地找到了这个过程

foreach (Process p in Process.GetProcesses())
{
  if (p.MainModule.FileName.ToLower().EndsWith("foo.exe"))
     FindChildWindowWithText(p); //do work
Run Code Online (Sandbox Code Playgroud)

问题是接下来要做什么.我不能使用Process' MainWindowText,因为它会随着激活的窗口而改变.

然后我试图使用Windows函数EnumChildWindowsGetWindowText,但我不知道如果我传递一个正确的句柄EnumChildWindows.在EnumChildWindows通过MainWindowHandle的时候,但当然,MainWindowHandle与活动窗口的变化按预期工作.所以我通过了Process.Handle,但是在切换应用程序的窗口时,我得到了不同的句柄和不同的结果.(据我所知,EnumChildWindows返回的句柄,不仅窗户,但控制在.NET讲,这是没有问题的,如果我能得到窗口的标题太)

也许我这样做是错误的,我需要一个不同的方法 - 再次,我的问题就像找到一个文本与特定正则表达式匹配的窗口一样简单.所以我可能需要一个枚举所有窗口的函数,这些窗口在任务栏中都是可见的.

谢谢

.net c# windows pinvoke process

9
推荐指数
1
解决办法
1万
查看次数

C#中的结构修改是否会影响非托管内存?

我的直觉反应是否定的,因为托管和非托管内存是截然不同的,但我不确定.NET Framework是否在幕后操作Marshaling.

我认为发生的是:从我的非托管DLL获取结构时,它与使调用获取IntPtr然后使用它和Marshal类将结构复制到托管内存(以及对托管中的结构所做的更改)相同记忆不要起泡).

我似乎无法在MSDN上的任何地方找到此文档.任何链接将不胜感激.

这是我的代码的样子:

[DllImport("mydll.dll", BestFitMapping=false, CharSet=CharSet.Ansi)]
private static extern int GetStruct(ref MyStruct s);

[StructLayout(LayoutKind.Sequential, Pack=0)]
struct MyStruct
{
     public int    Field1;
     public IntPtr Field2;
}

public void DoSomething()
{
      MyStruct s = new MyStruct();
      GetStruct(ref s);

      s.Field1 = 100; //does unmanaged memory now have 100 in Field1 as well?
      s.Field2 = IntPtr.Zero; //does unmanaged memory now have a NULL pointer in field Field2 as well?
}
Run Code Online (Sandbox Code Playgroud)

.net c# pinvoke struct

9
推荐指数
2
解决办法
579
查看次数

如何将F#委托传递给期望函数指针的P/Invoke方法?

我正在尝试在F#应用程序中使用P/Invoke设置一个低级键盘钩子.Win32函数SetWindowsHookEx接受HOOKPROC第二个参数,我将其表示为委托(int * IntPtr * IntPtr) -> IntPtr,类似于在C#中处理它的方式.在调用方法时,我得到一个MarshalDirectiveException声明,委托参数无法封送,因为

通用类型无法编组

我不确定如何涉及泛型,因为具体指定了所有类型.任何人都可以对此有所了解吗?代码如下.

编辑

这可能与F#编译器处理类型签名的方式有关 - Reflector指示委托LowLevelKeyboardProc实现为接受一个类型的参数的方法Tuple<int, IntPtr, IntPtr>- 并且将存在不可编组的泛型类型.有没有办法解决这个问题,或者F#函数是不是能够被编组到本机函数指针?

let WH_KEYBOARD_LL = 13

type LowLevelKeyboardProc = delegate of (int * IntPtr * IntPtr) -> IntPtr

[<DllImport("user32.dll")>]
extern IntPtr SetWindowsHookEx(int idhook, LowLevelKeyboardProc proc, IntPtr hMod, UInt32 threadId)

[<DllImport("kernel32.dll")>]
extern IntPtr GetModuleHandle(string lpModuleName)

let SetHook (proc: LowLevelKeyboardProc) =
    use curProc = Process.GetCurrentProcess ()
    use curMod = curProc.MainModule

    SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curMod.ModuleName), 0u)
Run Code Online (Sandbox Code Playgroud)

pinvoke winapi f# delegates

9
推荐指数
1
解决办法
1293
查看次数

在64位Windows上将字符串从C++返回到C#时,如何防止AccessViolationException?

我正在使用第三方专有DLL,我无法获得源代码.但是,使用SWIG 1.3.39自动生成的包装代码可供我使用.包装器代码包含一个C++文件,该文件编译(使用一些描述DLL的头文件)到DLL和一个C#项目,它使PInvoke调用C++包装器DLL.

根据我对供应商文档的解释,我已将解决方案中的所有内容编译为x86或x64,具体取决于目标平台.供应商提供专有DLL的32位和64位版本,并且我确保我使用正确的版本给定构建.我的机器是32位的.在我的机器上,在发布版本或调试版本中测试我的应用程序的x86版本似乎工作正常.但是,在64位上,应用程序在调试模式下工作,但在发布模式下因System.AccessViolationException而失败.

我已经阅读了这篇很好的博客文章,似乎很好地描述了调试与发布问题,以及引发博客文章的这个问题和答案.但是,我不确定如何在这种情况下解决问题.

AccessViolationException似乎是在第一次从C++包装器返回(或尝试返回)任何实际长度的字符串时发生的.这是违规的C#代码:

// In one file of the C# wrapper:
public string GetKey()
{
    // swigCPtr is a HandleRef to an object already created
    string ret = csWrapperPINVOKE.mdMUHybrid_GetKey(swigCPtr);
    return ret;
}

// In the csWrapperPINVOKE class in another file in the C# wrapper:
[DllImport("csWrapper.dll", EntryPoint="CSharp_mdMUHybrid_GetKey")]
public static extern StringBuilder mdMUHybrid_GetKey(HandleRef jarg1);
Run Code Online (Sandbox Code Playgroud)

来自C++包装器的麻烦的C++代码:

SWIGEXPORT char * SWIGSTDCALL CSharp_mdMUHybrid_GetKey(void * jarg1) {
  char * jresult ;
  mdMUHybrid *arg1 = (mdMUHybrid *) 0 ; …
Run Code Online (Sandbox Code Playgroud)

c++ pinvoke swig .net-4.0 access-violation

9
推荐指数
1
解决办法
4505
查看次数

如何调用Windows API

可能重复:
Windows API和.net语言

我想从.NET Framework调用本机Windows API.我希望有一个简单的方法,我可以像其他.NET API一样从高级层调用本机API.请参阅您知道的任何资源.任何帮助将不胜感激.

.net c# pinvoke winapi interop

9
推荐指数
2
解决办法
2万
查看次数

如何在C#中编组C++枚举

我需要在C++和C#之间创建一个包装器.我有一个非常类似的功能:

virtual SOMEINTERFACE* MethodName(ATTRIBUTE_TYPE attribType = ATTRIBUTE_TYPE::ATTRIB_STANDARD) = 0;
Run Code Online (Sandbox Code Playgroud)

enum声明如下:

enum class ATTRIBUTE_TYPE { 
    ATTRIB_STANDARD, 
    ATTRIB_LENGTH 
};
Run Code Online (Sandbox Code Playgroud)

如何包装ATTRIBUTE_TYPE枚举?

c# c++ pinvoke marshalling

9
推荐指数
1
解决办法
7678
查看次数

如何处理受约束执行区域中的分配?

约束执行区域是C#/ .Net的一个特性,它允许开发人员尝试从关键的代码区域中提升"三大"异常--OutOfMemory,StackOverflow和ThreadAbort.

CER通过推迟ThreadAborts,准备调用图中​​的所有方法来实现这一点(因此不会发生JIT,这可能导致分配),并确保有足够的堆栈空间来适应随后的调用堆栈.

典型的不间断区域可能如下所示:

public static void GetNativeFlag()
{
    IntPtr nativeResource = new IntPtr();
    int flag;

    // Remember, only the finally block is constrained; try is normal.
    RuntimeHelpers.PrepareConstrainedRegions();
    try
    { }
    finally
    {
        NativeMethods.GetPackageFlags( ref nativeResource );

        if ( nativeResource != IntPtr.Zero ) {
            flag = Marshal.ReadInt32( nativeResource );
            NativeMethods.FreeBuffer( nativeResource );
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

上述内容大部分都很好,因为CER内部没有任何规则被破坏 - 所有.Net分配都在CER之外,Marshal.ReadInt32()具有兼容性ReliabilityContract,我们假设我的NativeMethods被类似地标记,以便VM可以正确地考虑他们在准备CER时.

因此,除了所有这些之外,您如何处理分配必须在CER内部发生的情况?分配违反规则,因为很有可能获得OutOfMemoryException.

在查询本机API(SSPI的QuerySecurityPackageInfo)时,我遇到了这个问题,这会迫使我违反这些规则.本机API确实执行自己的(本机)分配,但如果失败,我只得到一个空的结果,所以没有什么大不了的.但是,在它分配的结构中,它存储了一些未知大小的C字符串.

当它返回指向它所分配的结构的指针时,我必须复制整个事物,并分配空间来存储这些c字符串作为.Net字符串对象.毕竟,我应该告诉它释放分配.

但是,由于我在CER中执行.Net分配,我违反规则并可能泄漏一个句柄.

处理这个问题的正确方法是什么?

对于它的价值,这是我天真的方法:

internal static SecPkgInfo GetPackageCapabilities_Bad( string packageName )
{
    SecPkgInfo info; …
Run Code Online (Sandbox Code Playgroud)

.net c# pinvoke

9
推荐指数
1
解决办法
412
查看次数

SetProcessDpiAwareness没有效果

我一直在尝试在ClickOnce应用程序上禁用DPI感知.
我很快发现,无法在清单中指定它,因为ClickOnce不支持清单文件中的asm.v3.

我找到的下一个选项是调用新的Windows函数SetProcessDpiAwareness.

根据教程,

在创建应用程序窗口之前调用SetProcessDpiAwareness.

教程中,

您必须在任何Win32API调用之前调用SetProcessDpiAwareness

你必须尽早调用这个函数.所以,为了测试,我创建了一个完全空白的WPF应用程序,并将其作为我的整个App类:

[DllImport("SHCore.dll", SetLastError = true)]
private static extern bool SetProcessDpiAwareness(PROCESS_DPI_AWARENESS awareness);

[DllImport("SHCore.dll", SetLastError = true)]
private static extern void GetProcessDpiAwareness(IntPtr hprocess, out PROCESS_DPI_AWARENESS awareness);

private enum PROCESS_DPI_AWARENESS
{
    Process_DPI_Unaware = 0,
    Process_System_DPI_Aware = 1,
    Process_Per_Monitor_DPI_Aware = 2
}

static App()
{
    var result = SetProcessDpiAwareness(PROCESS_DPI_AWARENESS.Process_DPI_Unaware);
    var setDpiError = Marshal.GetLastWin32Error();
    MessageBox.Show("Dpi set: " + result.ToString());

    PROCESS_DPI_AWARENESS awareness;
    GetProcessDpiAwareness(Process.GetCurrentProcess().Handle, out awareness);
    var getDpiError = Marshal.GetLastWin32Error();
    MessageBox.Show(awareness.ToString());

    MessageBox.Show("Set DPI error: …
Run Code Online (Sandbox Code Playgroud)

c# wpf clickonce pinvoke dpi

9
推荐指数
1
解决办法
6678
查看次数

标签 统计

pinvoke ×10

c# ×8

.net ×4

c++ ×2

winapi ×2

.net-4.0 ×1

access-violation ×1

clickonce ×1

delegates ×1

dpi ×1

f# ×1

interop ×1

marshalling ×1

process ×1

struct ×1

swig ×1

windows ×1

wpf ×1