标签: pinvoke

有没有办法调试从C#DllImport调用的c ++ dll?

我想知道是否有任何方法可以在VS 2010中调试从C#PInvoke调用的c ++ dll.我试图将项目附加到c#应用程序但它没有工作 - 没有停在断点处.

我还尝试在C++项目中使用OutputDebugString记录任何内容,但没有使用PInvoke调用打印.尽管存在这些问题,但实际功能运行良好.

任何建议将被认真考虑.

c# c++ pinvoke

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

为什么在Windows x64上IntPtr.size为4?

我想当我使用IntPtr.Size时我应该得到8.但是我仍然使用Widnows 7 x64在x64机器上获得4个,为什么?

c# pinvoke

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

为什么在.NET 4和3.5之间处理来自CloseHandle的异常?

我遇到的情况CloseHandle是,SEHException在调试器下运行时,PInvoke调用将在.NET 4应用程序中抛出.与其他遇到类似问题从3.5迁移到4的问题不同,我并没有特别担心这种行为,并且已经找到了问题(第三方库CloseHandle在同一个句柄上调用了两次).但是,我很困惑为什么在.NET 3.5应用程序中不会发生这种行为.

以下小但完整的示例演示了我遇到的行为(在XP SP3和Win 7 x64上测试,总是编译为x86):

class Program
{
    static void Main(string[] args)
    {
        try
        {
            var hFileMapping = CreateFileMapping(new IntPtr(-1), IntPtr.Zero, 0x04 /* read write */, 0, 0x1000, null);
            CloseHandle(hFileMapping);
            CloseHandle(hFileMapping);
            Console.WriteLine("No exception");
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }

        Console.ReadKey();
    }

    [DllImport("kernel32", SetLastError = true)]
    static extern IntPtr CreateFileMapping(IntPtr hFile, IntPtr lpAttributes, int flProtect, int dwMaximumSizeHigh, int dwMaximumSizeLow, string lpName);

    [DllImport("kernel32", SetLastError = true)]
    static extern bool CloseHandle(IntPtr handle); …
Run Code Online (Sandbox Code Playgroud)

.net c# pinvoke winapi interop

18
推荐指数
1
解决办法
2970
查看次数

C#调用C函数返回具有固定大小char数组的struct

所以,这个问题已经出现了很多变种,在看了几个后我仍然无法弄明白.

这是C代码:

typedef struct
{
unsigned long Identifier;
char Name[128];
} Frame;

Frame GetFrame(int index);
Run Code Online (Sandbox Code Playgroud)

这是C#代码:

struct Frame
{
    public ulong Identifier;
    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.I1, SizeConst = 128)]
    public char[] Name;
}

[DllImport("XNETDB.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
private static extern Frame GetFrame(int index);
Run Code Online (Sandbox Code Playgroud)

这是我在C#中尝试过的最后一次尝试,看起来非常符合逻辑,但我得到的错误是"方法的签名与PInvoke不兼容".所以,我有点迷失下一步的尝试.任何帮助表示赞赏.

谢谢,凯文

Kevin 更新了这个作为我的答案的编辑

我应该改变我的C代码:

void GetFrame(int index, Frame * f);
Run Code Online (Sandbox Code Playgroud)

并使用C#代替:

struct Frame
{
    public uint Identifier;
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 128)]
    public string Name;
}

[DllImport("XNETDB.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] …
Run Code Online (Sandbox Code Playgroud)

c# pinvoke

18
推荐指数
2
解决办法
7706
查看次数

对PInvoke函数的调用使堆栈失衡.这很可能是因为托管的PInvoke ..(.NET 4)

我的项目在.NET Frame 3.5中成功运行且没有错误.但是,当我将它定位到.NET Frame工作4.我得到了错误:

" 对PInvoke函数的调用使堆栈失衡.这可能是因为托管的PInvoke签名与非托管目标签名不匹配. "

我使用了非托管库,如下所示:

[StructLayout(LayoutKind.Sequential )]
public class DGNElemCore
{
    public int offset;
    public int size;
    public int element_id;
    public int stype;          
    public int level;
    public int type;
    public int complex;
    public int deleted;
    public int graphic_group;
    public int properties;
    public int color;
    public int weight;
    public int style;
    public int attr_bytes;       
    public IntPtr attr_data;  
    public int raw_bytes;
    public IntPtr raw_data;                 

}

[DllImport("DgnLib.dll", EntryPoint = "DGNOpen")]           
public static extern IntPtr  DGNOpen(string fileName, int bUpdate)
Run Code Online (Sandbox Code Playgroud)

你知道如何解决这个错误吗?

.net c# pinvoke

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

正确的方法来组织SIZE_T*?

我有以下C++函数定义,我试图通过托管代码通过PInvoke调用:

bool FooBar(SIZE_T* arg1);
Run Code Online (Sandbox Code Playgroud)

我的管理声明如下:

[DllImport("mydll", SetLastError=true, CharSet=CharSet.Unicode)]
private static extern bool FooBar(ref uint arg1);
Run Code Online (Sandbox Code Playgroud)

有些人可能会注意到我最终做的同样的错误.这不是64位便携式.SIZE_T的大小可变(32-64位),指针也是如此.在托管大小上,指针正确转换为64位,但uint没有,并且您最终可以在arg1的高位中使用垃圾.这是一个特别持久的错误,因为垃圾通常只是零:(

我已经开始工作的唯一解决方案是以下管理声明:

[DllImport("mydll", SetLastError=true, CharSet=CharSet.Unicode)]
private static extern bool FooBar(ref IntPtr arg1);
Run Code Online (Sandbox Code Playgroud)

这当然有效,因为IntPtr可以正确地改变它的大小.在我的代码中,我只是将IntPtr视为一个整数,它可以工作,虽然它看起来像一个丑陋的黑客.在我看来应该有一些方法来正确指定,也许使用UnmanagedType.SysUInt,但我无法提出任何其他工作解决方案.

c# c++ pinvoke marshalling intptr

17
推荐指数
2
解决办法
9754
查看次数

pInvoke和COM Interop有什么区别?

让我们说我正在访问第三方库,其文档声明我可以使用pInvoke或创建互操作库并使用COM.这两种技术有什么区别,为什么我可以选择其中一种?

.net com pinvoke

17
推荐指数
1
解决办法
4118
查看次数

在C#中以编程方式锁定Windows工作站

我遇到了锁定Windows工作站的示例:

using System.Runtime.InteropServices;
...
[DllImport("user32.dll", SetLastError = true)]
static extern bool LockWorkStation();

...
if (!LockWorkStation())
    throw new Win32Exception(Marshal.GetLastWin32Error()); // or any other thing
Run Code Online (Sandbox Code Playgroud)

这个片段有一个纯粹的托管替代方案吗?即,没有P-Invoke.

c# windows pinvoke pure-managed

16
推荐指数
1
解决办法
7452
查看次数

C#没有捕获来自非托管C++ DLL的未处理异常

我有一个从C#应用程序调用的非托管C++ DLL,我试图让C#应用程序捕获所有异常,以便在由于非托管异常导致dll失败的情况下,用户将得到一个半合适的错误消息(C#app是一个实现它自己的http处理程序的Web服务).

我遇到的问题是并非所有类型都被捕获.因此,如果我创建以下内容并执行C#应用程序,则dll会抛出错误并终止整个应用程序.有任何想法吗?

这是在VS2005中使用.Net framework v2创建的

C++ - Test.h

#ifndef INC_TEST_H
#define INC_TEST_H

extern "C" __declspec(dllexport) void ProcessBadCall();

#endif
Run Code Online (Sandbox Code Playgroud)

C++ - Test.cpp

#include <iostream>
#include <vector>

using namespace std;

void ProcessBadCall()
{
  vector<int> myValues;
  int a = myValues[1];
  cout << a << endl;
}
Run Code Online (Sandbox Code Playgroud)

C# - Program.cs

class Program
{
  [DllImport("Test.dll", EntryPoint="ProcessBadCall")]
  static extern void ProcessBadCall();

  static void Main(string[] args)
  {
    try
    {
      ProcessBadCall();
    }
    catch (SEHException ex)
    {
      Console.WriteLine("SEH Exception: {0}", ex.Message);
    }
    catch (Exception ex)
    {
      Console.WriteLine("Exception: {0}", …
Run Code Online (Sandbox Code Playgroud)

c# c++ dll pinvoke exception-handling

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

在WPF窗口中挂钩进入Windows消息循环,在内部添加白色边框

我正在尝试创建一个WPF窗口WindowStyle="None"(用于自定义按钮,没有标题),无法调整大小.设置ResizeModeNoResize删除我想要保留的空气边界.

我可以设置最小/最大尺寸属性并完成它,除了:

  1. 调整大小的游标仍然可见,并且
  2. 显示窗口以响应用户操作并适合其内容.它显示图像,因此大小会发生变化.

所以,我有一个简单的方案,让我99%的方式:

public class BorderedWindowNoResize : Window
{
    [DllImport( "DwmApi.dll" )]
    public static extern int DwmExtendFrameIntoClientArea(
        IntPtr hwnd,
        ref MARGINS pMarInset );

    [DllImport( "user32.dll", CharSet = CharSet.Auto )]
    public static extern IntPtr DefWindowProc(
        IntPtr hWnd,
        int msg,
        IntPtr wParam,
        IntPtr lParam );

    public BorderedWindowNoResize()
    {           
        Loaded += BorderedWindowNoResize_Loaded;
    }

    private void BorderedWindowNoResize_Loaded( object sender, RoutedEventArgs e )
    {           
        IntPtr mainWindowPtr = new WindowInteropHelper( this ).Handle;
        HwndSource mainWindowSrc = HwndSource.FromHwnd( mainWindowPtr ); …
Run Code Online (Sandbox Code Playgroud)

c# wpf pinvoke

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

标签 统计

pinvoke ×10

c# ×9

.net ×3

c++ ×3

com ×1

dll ×1

exception-handling ×1

interop ×1

intptr ×1

marshalling ×1

pure-managed ×1

winapi ×1

windows ×1

wpf ×1