标签: pinvoke

如何在C#中使用p/invoke将指针传递给数组?

示例C API签名:

void Func(unsigned char* bytes);

在C中,当我想将指针传递给数组时,我可以这样做:

unsigned char* bytes = new unsigned char[1000];
Func(bytes); // call
Run Code Online (Sandbox Code Playgroud)

如何将上述API转换为P/Invoke,以便我可以将指针传递给C#字节数组?

c c# api pinvoke

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

以编程方式移动鼠标光标

首先,我在http://swigartconsulting.blogs.com/tech_blender/2005/08/how_to_move_the.html找到了此代码:

public class Win32
{
    [DllImport("User32.Dll")]
    public static extern long SetCursorPos(int x, int y);

    [DllImport("User32.Dll")]
    public static extern bool ClientToScreen(IntPtr hWnd, ref POINT point);

    [StructLayout(LayoutKind.Sequential)]
    public struct POINT
    {
        public int x;
        public int y;
    }
}
Run Code Online (Sandbox Code Playgroud)

将以下代码粘贴到按钮的click eventhandler中:

Win32.POINT p = new Win32.POINT();
p.x = button1.Left + (button1.Width / 2);
p.y = button1.Top + (button1.Height / 2);

Win32.ClientToScreen(this.Handle, ref p);
Win32.SetCursorPos(p.x, p.y);
Run Code Online (Sandbox Code Playgroud)

这会将鼠标指针移动到按钮的中心.

这段代码效果很好,但我似乎无法弄清楚如何扩展它.假设我有一个Internet浏览器(嵌入在windows窗体中)打开一个网页(一些我手头不知道的随机页面),里面有一个下拉列表框.我已修改上面的代码,将光标移动到下拉列表框(使用下面显示的鼠标单击方法将列表向下拖放),并在列表中上下移动,突出显示每个项目作为鼠标指针过去,但对于我的生活,我无法弄清楚如何实际让鼠标点击当前选定的项目来保持选择.我正在这样做的方式现在下拉列表框只是关闭,选择不会改变.我正在使用以下代码进行鼠标单击(这会使列表下拉):

private static void MouseClick(int x, int y, IntPtr handle) //handle for the browser …
Run Code Online (Sandbox Code Playgroud)

c# mouse pinvoke internet-explorer cursor

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

这个PInvoke代码是否正确可靠?

这个问题中,我搜索了一个解锁文件的简单解决方案.感谢所有的评论和回答,我找到了PInvoking的简单解决方案DeleteFile.

它工作,但因为我从来没有通过PInvoke(Win32)使用文件操作,我不知道是否有一些陷阱或是否有另一种方法来调用DeleteFile删除文件的备用流.

我还不知道的是,如果我必须在try/catch中包装调用,或者仅仅查看布尔结果就足够了.在我的测试中,没有提出异常,但我不知道在现实世界中会发生什么.

public class FileUnblocker {

    [DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool DeleteFile(string name );

    public bool Unblock(string fileName) {
        return DeleteFile(fileName+ ":Zone.Identifier");
    }
}
Run Code Online (Sandbox Code Playgroud)

这段代码看起来可靠吗?

更新
我发布了一个不完整的方法(unblock方法没有将"Zone.Identifier"文字连接到文件名).我现在纠正了这个,抱歉.

.net c# pinvoke .net-4.0 alternate-data-stream

21
推荐指数
2
解决办法
3399
查看次数

C#中的元帅"char*"

给定DLL中的以下C函数:

char * GetDir(char* path );
Run Code Online (Sandbox Code Playgroud)

你将如何P/Invoke这个函数到C#并正确编组char*..NET似乎知道如何做LPCTSTR,但是当我无法找出任何不会导致NotSupportedException在调用此函数时触发的编组时.

.net pinvoke marshalling

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

生成P/Invoke代码的最简单方法是什么?

我是一位经验丰富的.Net程序员,但在我的生活中还没有编译过C/C++程序.现在我有这个C-dll,标题和文档(第三方,而不是来自Win API),我需要从中调用十种方法.

我在考虑使用Platform Invoke.我发现这三个工具可以为我创建代码:

可能

  • Swig:http://www.swig.org/

Pinvoker似乎与Interop助手和向导有一些不同的方法.Swig我刚刚检查时发现这个问题没有在这里提出.

这些工具的优缺点是什么?

鉴于我对C/C++知之甚少,对我来说生成P/Invoke代码的最佳=最简单,最安全的方法是什么?

c c# pinvoke

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

为什么我不能在Release版本中将C++中的char*字符串返回给C#?

我试图从C#调用以下简单的C函数:

SIMPLEDLL_API const char* ReturnString()
{
    return "Returning a static string!";
}
Run Code Online (Sandbox Code Playgroud)

使用以下P/Invoke声明(使用或不使用return属性,它没有区别):

[DllImport("SimpleDll")]
[return: MarshalAs(UnmanagedType.LPStr)]
public static extern string ReturnString();
Run Code Online (Sandbox Code Playgroud)

如果DLL是Debug构建但在Release构建(AccessViolationException)中崩溃,则它可以工作.

我正在调用十几个其他简单的函数,这是唯一失败的函数(这里是其他函数:)

[DllImport("SimpleDll")] public static extern int NextInt();
[DllImport("SimpleDll")] public static extern void SetNextInt(int x);
[DllImport("SimpleDll")] public static extern int AddInts(int a, int b);
[DllImport("SimpleDll")] public static extern int AddFourInts(int a, int b, int c, int d);
[DllImport("SimpleDll")] public static extern double AddDoubles(double x, double y);
[DllImport("SimpleDll")] public static extern IntPtr AddDoublesIndirect(ref double x, ref double y);
[DllImport("SimpleDll")] [return: …
Run Code Online (Sandbox Code Playgroud)

.net pinvoke marshalling access-violation

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

如何将const char*从C#传递给C函数?

我尝试从我的C#-application中调用来自外部DLL的普通C函数.此功能定义为

void set_param(const char *data)
Run Code Online (Sandbox Code Playgroud)

现在我使用这个函数有一些问题:

  1. 如何在C#代码中指定此"const"?public static extern void set_param(sbyte *data)似乎错过了"const"部分.

  2. 调用此函数时,如何移交普通的8位C字符串?调用set_param("127.0.0.1")导致错误消息"无法从'string'转换为'sbyte '"*.

.net c# dll pinvoke marshalling

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

从c头自动创建C#包装器?

有没有办法从ac头自动创建.net的p/invoke包装?

当然我可以手工创建它们,但维护它们会很痛苦,而且我可能在某个地方犯了一个错误,导致很难调试崩溃.

我尝试过SWIG,但它创建了完整的类,其中简单的结构就足够了.SWIG的另一个问题是它需要c侧的额外互操作代码.

我更喜欢输出也适用于单声道,但这不是必需的.

我可以使用的另一件事是一个解析c头的程序,并以一个漂亮的中间格式(如xml)创建一个输出,我可以自己创建C#包装器.

编辑:
PInvoke Interop助手是我需要的.
但它有一些小问题:
*它将"unsigned char*"转换为我更喜欢IntPtr的字符串
*它假设size_t = int = long = 32bit.这对我来说是正确的,但在每个平台上可能都不是这样.
有没有一个干净的方法来解决这个问题?否则我会在转换之前在c代码上使用一些查找和替换.

.net c c# pinvoke interop

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

在服务器桌面会话上捕获屏幕

我开发了一个GUI测试框架,可以按计划对我们公司网站进行集成测试.当某些内容失败时,它会截取桌面的屏幕截图等.这在专用Windows Server 2008上的登录用户上无人值守.

问题是在我已断开远程桌面会话的桌面上截取屏幕截图.我得到以下异常:

System.ComponentModel.Win32Exception (0x80004005): The handle is invalid     
at System.Drawing.Graphics.CopyFromScreen(Int32 sourceX, Int32 sourceY, Int32 destinationX, Int32 destinationY, Size blockRegionSize, CopyPixelOperation copyPixelOperation)     
at System.Drawing.Graphics.CopyFromScreen(Point upperLeftSource, Point upperLeftDestination, Size blockRegionSize)     
at IntegrationTester.TestCaseRunner.TakeScreenshot(String name) in C:\VS2010\IntegrationTester\IntegrationTester\Config\TestCaseRunner.cs:line 144     
at IntegrationTester.TestCaseRunner.StartTest() in C:\VS2010\IntegrationTester\IntegrationTester\Config\TestCaseRunner.cs:line 96
Run Code Online (Sandbox Code Playgroud)

TakeScreenshot()方法是这样的:

public static void TakeScreenshot(string name)
        {
            var bounds = Screen.GetBounds(Point.Empty);
            using (Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height))
            {
                using (Graphics g = Graphics.FromImage(bitmap))
                {
                    g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);
                }
                bitmap.Save("someFileName", ImageFormat.Jpeg);
            }
        }
Run Code Online (Sandbox Code Playgroud)

我确保屏幕保护程序设置为"无",没有超时.我还实现了一段代码,它可以执行一些pinvokes来发送鼠标移动,希望它能生成桌面图形处理..但是没有. …

.net c# pinvoke system.drawing windows-server-2008

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

在C#中使用pinvoke时,[In,Out]和ref之间有什么区别?

使用[In,Out]和将参数从C#传递给C++时只使用ref有什么区别吗?

我发现了几个不同的SO帖子,以及来自MSDN的一些东西也接近我的问题,但并没有完全回答它.我的猜测是我可以安全地使用ref,就像我使用[In,Out]一样,并且marshaller将不会采取任何不同的行为.我担心的是它会采取不同的行为,并且C++对我传递的C#结构不满意.我已经在我正在使用的代码库中看到了两件事情......

以下是我发现并一直在阅读的帖子:

P/Invoke [In,Out]属性是否可选用于编组数组? 让我觉得我应该使用[In,Out].

这三个帖子让我觉得我应该使用[In,Out],但我可以使用ref代替它,它将具有相同的机器代码.这让我觉得我错了 - 所以问这里.

c# pinvoke

19
推荐指数
1
解决办法
4876
查看次数