标签: pinvoke

C# 和本机重叠 I/O

我有一个正在包装的 C dll,以便可以从 C# 调用它。当状态发生变化时,一个函数使用事件来通知您,并且需要进行一些挖掘才能找到处理它的方法。它似乎工作正常,但我很好奇是否有人比我有更多的经验并且可以提供任何建议。

该函数在 dll 的 .h 文件中定义为:

int NotifyStateChange(OVERLAPPED *overlapped);  
typedef int (*NOTIFY_STATE_CHANGE_PROC)(OVERLAPPED *);  
Run Code Online (Sandbox Code Playgroud)

调用它的示例 C 代码:

OVERLAPPED overlapped;  
overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);  
fns.NotifyStateChange(&overlapped);  
WaitForSingleObject(overlapped.hEvent, INFINITE);  
// ...query for the new state or whatever...
Run Code Online (Sandbox Code Playgroud)

这就是我在 C# 中的处理方式:

[DllImport("myfuncs.dll")]
unsafe public static extern int NotifyStateChange(NativeOverlapped* lpOverlapped);

static private ManualResetEvent m_stateChangeEvent = new ManualResetEvent(false);

public static DeviceState WaitForStateChange()
{
    unsafe
    {
        Overlapped overlapped = new Overlapped(0, 0, 
            m_stateChangeEvent.SafeWaitHandle.DangerousGetHandle(), null);
        IOCompletionCallback callback = StateChangeCallback;
        byte[] userData = new …
Run Code Online (Sandbox Code Playgroud)

c# pinvoke overlapped-io

3
推荐指数
1
解决办法
7934
查看次数

如何在 C# 中最小化/恢复窗口

我正在尝试最小化标题位于string p(由用户在运行时指定)中的窗口。该窗口保证是主窗口,因为用户只能从主窗口中进行选择。我尝试过 showCmd、flags 以及两者的混合,但每次,无论窗口是否最小化,我都会显示一个声明 的对话框"Minimizing"。我该如何修复它?

private void button1_Click(object sender, EventArgs e)
{
    foreach (Process proc in Process.GetProcesses())
    {
        if (proc.MainWindowTitle.Contains(p))
        {
            IntPtr handle = proc.Handle;
            Program.WINDOWPLACEMENT wp = new Program.WINDOWPLACEMENT();
            Program.GetWindowPlacement(handle, ref wp);
            if ((wp.showCmd & 2) == 2)
            {
                wp.showCmd = 9;
                MessageBox.Show("Restoring");
            }
            else
            {
                wp.showCmd = 2;
                MessageBox.Show("Minimizing");
            }
            wp.length = Marshal.SizeOf(wp);
            Program.SetWindowPlacement(handle, ref wp);
            break;
        }
    }  

}
Run Code Online (Sandbox Code Playgroud)

我用什么作为 p -

string p;
PictureBox i;
bool windowShowing = false;
bool minimized = …
Run Code Online (Sandbox Code Playgroud)

c# pinvoke native

3
推荐指数
1
解决办法
3820
查看次数

使用自定义封送拆收器时的 C# Marshal.Sizeof()

是否可以在使用自定义封送拆收器的结构上使用Marshal.SizeOf()

例如:

struct Abcde { 
  public int test1;
  [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(MyCustomMarshaler)]
  public string customString1;
}
Run Code Online (Sandbox Code Playgroud)

如果我打电话:

var size = Marshal.SizeOf(typeof(Abcde));
Run Code Online (Sandbox Code Playgroud)

抛出一个异常,表示无法计算有意义的大小或偏移量。我注意到ICustomMarshaler有一个名为GetNativeDataSize()的方法,但是无论我在那里返回什么都会抛出异常。

c# pinvoke marshalling

3
推荐指数
1
解决办法
487
查看次数

Pinvoke - 来自 C++ 的回调,函数之间传递的数组具有意外大小

编辑:我已经根据@Hans Passant 的评论和@David Heffernan 的回答中的建议更新了代码。

这个论点c不再为空,但两者xc仍然有一个长度,当它们被传递回CallbackFunction

我正在尝试编写将函数指针(使用委托)传递给调用函数指针的 C++ 函数的 C# 代码。

代码如下。

我遇到的问题是,当 C++ 函数f调用时fnPtr(x,c),在 C# 函数中CallbackFunctionx有一个元素(正确值为 1.0),并且c为空。我不知道问题是什么。

我无法更改 MyCallback 的签名。

C#代码:

using System.Runtime.InteropServices;

namespace PInvokeTest
{
    class Program
    {
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        private delegate double MyCallback(
            [In] double[] x,
            [Out] double[] c);

        private static double CallbackFunction(
            [In] double[] x,
            [Out] double[] c)
        {
            c[0] = x[0] + x[1] + x[2];
            c[1] = x[0] …
Run Code Online (Sandbox Code Playgroud)

c# pinvoke marshalling

3
推荐指数
1
解决办法
1420
查看次数

将字符数组从 c# 传递到 c++ dll

我有一个 LZ4 c 实现的 dll,我想调用

LZ4_compress_default(const char* source,char* dest,int sourceLength,int maxdestLength);
Run Code Online (Sandbox Code Playgroud)

来自 ac# 代码的函数。该函数将源数组压缩为目标数组。这该怎么做?

我的 C# 代码:

DllImport(@"CXX.dll", CharSet = CharSet.Ansi, SetLastError = true, 
    CallingConvention = CallingConvention.Cdecl)] 
internal static extern int LZ4_compress_default(
    [MarshalAs(UnmanagedType.LPArray)] char[] source, out byte[] dest, 
    int sourceSize, int maxDestSize); 


byte[] result= new byte[maxSize]; 
int x = LZ4_compress_default(array, out result, size, maxSize); 
Run Code Online (Sandbox Code Playgroud)

c# pinvoke dllimport

3
推荐指数
1
解决办法
5464
查看次数

如何从DLL中提取字符串资源

我正在制作一个管理系统文件扩展名的应用程序,我遇到了问题。

系统扩展喜欢.jpg.exe.dll.png.txt,等有一个名为注册表值FriendlyTypeName,例如,FriendlyTypeName一个JPEG文件的是@%SystemRoot%\System32\shell32.dll,-30596。显示值取决于当前语言。

如何-30596使用 C#从资源 ID(例如:)中提取字符串值?。我想可以使用 p/invoke 提取字符串(我不确定)。

c# dll pinvoke

3
推荐指数
1
解决办法
3974
查看次数

如何在 WinForms 系统菜单中显示带有图标和文本的菜单项

在调整ygoe答案时,我发现可以在菜单中添加一个图标。

通过将此代码用于纯文本项目,我尝试并成功地做到了这一点:

var item = new MenuItemInfo
{
  cbSize = (uint)Marshal.SizeOf(typeof(MenuItemInfo)),
  cch = (uint)label.Length,
  dwTypeData = label,
  fMask = 0x2 | 0x10, // MIIM_ID | MIIM_TYPE
  fState = 0x0,       // MFS_ENABLED
  fType = 0x0,        // MFT_STRING
  wID = id
};
InsertMenuItem(hMenu, 0, true, ref item);
Run Code Online (Sandbox Code Playgroud)

对于基于图标的项目,我更改fMask并添加hbmpItem如下:

var item = new MenuItemInfo
{
  cbSize = (uint)Marshal.SizeOf(typeof(MenuItemInfo)),
  cch = (uint)label.Length,
  dwTypeData = label,
  fMask = 0x80 | 0x2 | 0x100, // MIIM_BITMAP | MIIM_ID …
Run Code Online (Sandbox Code Playgroud)

c# pinvoke winapi menuitem winforms

3
推荐指数
1
解决办法
1357
查看次数

C# 如何调用/调用 NtRaiseHardError

以下 C++ 代码会导致蓝屏。

    #include "stdafx.h"
    #include <iostream>
    #include <string>
    #include <Windows.h>

    #pragma comment(lib, "ntdll.lib")


    using namespace std;


    EXTERN_C NTSTATUS NTAPI RtlAdjustPrivilege(ULONG, BOOLEAN, BOOLEAN, PBOOLEAN);

    EXTERN_C NTSTATUS NTAPI NtRaiseHardError(NTSTATUS, ULONG, ULONG, PULONG_PTR, ULONG, PULONG);

    int main(int argc, char **argv)
    {
        BOOLEAN bl;
        RtlAdjustPrivilege(19, TRUE, FALSE, &bl);
        unsigned long response;
        NtRaiseHardError(STATUS_ASSERTION_FAILURE, 0, 0, 0, 6, &response);
        return 0;
    }
Run Code Online (Sandbox Code Playgroud)

我想为此使用 C#,所以我尝试使用 P/Invoke。但它不起作用。问题出在 NtRaiseHardError 签名上。我还没有在网上找到任何关于它的信息(例如 pinvoke.net 没有显示 NtRaiseHardError 因为它没有记录。)
这是我尝试过的:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Runtime.InteropServices;
    using …
Run Code Online (Sandbox Code Playgroud)

c# pinvoke c++-cli blue-screen-of-death

3
推荐指数
1
解决办法
3678
查看次数

调用“ShutdownBlockReasonCreate”函数不会阻止用户关闭系统

这篇文章说:

如果应用程序必须阻止潜在的系统关闭,它可以调用 ShutdownBlockReasonCreate 函数。调用者提供将显示给用户的原因字符串。

ShutdownBlockReasonCreate文档中,它清楚地表明在尝试关闭时将向用户显示一个带有原因字符串的对话框窗口:

表示系统无法关闭,并设置一个原因字符串,如果系统启动,则显示给用户

讨论中确认了对话框窗口的出现:

用户可以单击“仍然关闭”。此外,如果用户在几秒钟内没有采取任何行动,系统会假设“无论如何都要关闭”。

但是,在我调用ShutdownBlockReasonCreate传递当前应用程序的主窗口句柄后,确保该函数成功并通过调用ShutdownBlockReasonQuery函数来检索原因字符串来双重确保它,它不会阻止用户关闭系统和没有对话框窗口显示。

为什么它对我的系统没有影响?,我该如何解决这个问题?。

我使用管理员(内置)帐户在 Windows 10 x64 上运行,我使用的代码来自GitHub 存储库:

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Vanara.PInvoke;
using static Vanara.PInvoke.User32;

namespace Vanara.Windows.Forms.Forms
{
    /// <summary>Used to define a set of operations within which any shutdown request will be met with a reason why this application is blocking it.</summary>
    /// <remarks>This is to be used in either a 'using' statement or …
Run Code Online (Sandbox Code Playgroud)

.net c# pinvoke winapi shutdown

3
推荐指数
1
解决办法
1372
查看次数

如何从C#中的C++ dll获取数组的内容

我想在 C++ 和 C# 中使用来自 DLL 的函数。

我将字符串数据存储在向量中。

我的 C++ 文件包含:

#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

extern "C" __declspec(dllexport) std::vector<std::string> GetProduct();

std::vector<std::string> GetProduct()
{
  std::vector<std::string> vectProduct;
  vectProduct.push_back("Citroen");
  vectProduct.push_back("C5");
  vectProduct.push_back("MOP-C5");
  return vectProduct;
}
Run Code Online (Sandbox Code Playgroud)

在 C# 中

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Runtime.InteropServices;
namespace ConsoleApplication
{
    class Program
    {
        [DllImport("ProductLibrary.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern StringBuilder GetProduct();

        static void Main(string[] args)
        {
            StringBuilder vectProduct_impl = GetProduct();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我不知道如何在c#中继续浏览数组。我不知道使用向量是否最佳。如果你有其他解决方案,我准备好了。 …

c# c++ pinvoke

3
推荐指数
1
解决办法
210
查看次数