标签: pinvoke

PInvokeStackImbalance C#调用非托管C++函数

切换到VS2010后,托管调试助手在从C#应用程序调用非托管C++函数时显示有关不平衡堆栈的错误.

通常的嫌疑人似乎没有引起这个问题.还有别的我应该检查一下吗?VS2008构建的C++ DLL和C#应用程序从来没有出现问题,没有奇怪或神秘的错误 - 是的,我知道这并不意味着什么.

以下是检查的内容:

  • dll名称是正确的.
  • 入口点名称是正确的,并已使用depends.exe验证 - 代码必须使用受损的名称,它确实如此.
  • 调用约定是正确的.
  • 尺寸和类型似乎都是正确的.
  • 字符集是正确的.
  • 忽略错误后似乎没有任何问题,并且在调试器外部运行时没有问题.

C#:

[DllImport("Correct.dll", EntryPoint = "SuperSpecialOpenFileFunc", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi, ExactSpelling = true)]
public static extern short SuperSpecialOpenFileFunc(ref SuperSpecialStruct stuff);

[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
public struct SuperSpecialStruct
{
   public int field1;
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
   public string field2;
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
   public string field3;
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
   public string field4;
   public ushort field5;
   public ushort field6;
   public ushort field7;
   public …
Run Code Online (Sandbox Code Playgroud)

c# c++ pinvoke dllimport visual-studio-2010

39
推荐指数
3
解决办法
4万
查看次数

将字符串从C#传递到C++ DLL并返回 - 最小的例子

我试图制作绝对最简单的最小例子,说明如何在C#中向C++ DLL传递字符串.

我的C++看起来像这样:

using std::string;

extern "C" {
    string concat(string a, string b){
        return a + b;
    }
}
Run Code Online (Sandbox Code Playgroud)

像标题一样

using std::string;

extern "C" {
    // Returns a + b
    __declspec(dllexport) string concat(string a, string b);
}
Run Code Online (Sandbox Code Playgroud)

我的C#是

[DllImport("*****.dll", CallingConvention = CallingConvention.Cdecl)]
    static extern string concat(string a, string b);
}
Run Code Online (Sandbox Code Playgroud)

我用它来调用它:Console.WriteLine(concat("a","b"));

但是这会产生System.AccessViolationException.这似乎是处理最琐碎的事情,但我完全坚持下去.当我尝试使用"添加"功能进行类似的实验,这个功能需要两个双打并且返回一个双重而没有问题.

c# c++ pinvoke

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

从调试过程MainModule获取符号

我开始用C#编写调试器,以调试我的操作系统上的任何进程.目前,它只能处理断点(HW,SW和内存),但现在我想显示进程的操作码.

我的第一次尝试是使用nidsasm(NASM),但这不合适,因为启动后a.Net应用程序汇编程序指令与ndisasm(使用CheatEngine测试)不同.

所以我搜索了一段时间,发现dbghelp.dll中的一些方法,可以调用它们列出所有加载的模块和符号(加上基地址).好吧,我的尝试是,用SharpDisasm分别拆解所有模块.

ProcessModuleCollection modules = ProcessData.Instance.MPMR.ReadProcess.Modules;用来获取进程的所有加载模块.这非常有效.

现在我尝试加载MainModule的符号,但此时,我坚持实现.我用p/Invoke和SymInitialize等其他必要的函数实现了SymEnumSymbols函数.

当我使用例如"User32.dll"的BaseAddress调用它时,所有符号都打印得很完美,但对于MainModule,我没有得到任何符号.

这是来自CheatEngine的截图: 从Cheat Engine获得的符号

正如你所看到的,有像"Form1_Load"这样的符号,我的实现并没有这些符号.

这是必要的代码示例:

if (!DebugApi.SymInitialize(ProcessData.Instance.MPMR.M_hProcess, null, false))
{
    var err = Marshal.GetLastWin32Error();

    //throw new Exception("GetMemoryInfo failed : GetLastError() : " + new Win32Exception(err).Message);
    Console.WriteLine("GetMemoryInfo failed : GetLastError() : " + new Win32Exception(err).Message);
    return;
}

if (!DebugApi.SymEnumSymbols(ProcessData.Instance.MPMR.M_hProcess, (ulong)ProcessData.Instance.MPMR.ReadProcess.MainModule.BaseAddress, "!", DebugApi.EnumSyms, IntPtr.Zero))
{
    var err = Marshal.GetLastWin32Error();

    //throw new Exception("GetMemoryInfo failed : GetLastError() : " + new Win32Exception(err).Message);
    Console.WriteLine("GetMemoryInfo failed : GetLastError() : " + new Win32Exception(err).Message);
    return;
} …
Run Code Online (Sandbox Code Playgroud)

c# debugging pinvoke debug-symbols

37
推荐指数
1
解决办法
1333
查看次数

向IntPtr添加偏移量

我正在寻找一种在C#或.NET中执行指针操作的方法.

我想做一些非常简单的事情

有一个指针IntPtr我想获得指向前2个字节的IntPtr对象.

我读了一些帖子,说这个愚蠢的片段会起作用......

IntPtr ptr = new IntPtr(oldptr.ToInt32() + 2);
Run Code Online (Sandbox Code Playgroud)

但我怀疑这个语句是否也适用于64位机器(因为在那里寻址是64位).

我发现这种优雅的方法来添加偏移量,但不幸的是只在.NET 4.0中http://msdn.microsoft.com/en-us/library/system.intptr.add%28VS.100%29.aspx

.net c# pinvoke interop

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

正确的方式(在.NET中)将焦点切换到另一个应用程序

这是我到目前为止:

    Dim bProcess = Process.GetProcessesByName("By").FirstOrDefault
    If bProcess IsNot Nothing Then
        SwitchToThisWindow(bProcess.MainWindowHandle, True)
    Else
        Process.Start("C:\Program Files\B\B.exe")
    End If
Run Code Online (Sandbox Code Playgroud)

它有两个问题.

  1. 有些人告诉我,SwitchToThisWindow已被删除.
  2. 如果应用程序B被最小化,则从用户的角度来看,此功能无声地失败.

那么这样做的正确方法是什么?

.net pinvoke process

35
推荐指数
4
解决办法
6万
查看次数

用于包装C库的P/Invoke或C++/CLI

具有中等大小(40多个函数)的C API,需要从C#项目调用.这些函数在逻辑上分解,形成一些类,这些类将呈现给项目的其余部分.

在稳健性,可维护性,部署......方面,是否有任何客观理由倾向于使用P/Invoke或C++/CLI来实现该API下的互操作性?

我能想到的问题可能是,但没有问题的是:

  • C++/CLI将需要单独的程序集,P/Invoke类可以在主程序集中.(我们已经有多个程序集,无论如何都会有C dll,所以不是主要问题).
  • 两种方法之间的性能似乎没有明显差异.

我不确定的问题是:

  • 我的感觉是,如果存在操作间问题,C++/CLI将更容易调试,这是真的吗?
  • 语言熟悉程度足以让人知道C#和C++,但是对C++/CLI细节的了解却很少见.

还要别的吗?

.net c# pinvoke c++-cli

34
推荐指数
3
解决办法
9500
查看次数

是否有工具为任意非托管DLL生成P/Invoke签名?

我偶然发现了一个为Microsoft自己的非托管DLL生成P/Invoke签名的工具:PInvoke Interop Assistant

是否有类似的工具将为第三方非托管DLL生成P/Invoke签名?

或者,任何方式将第三方DLL提供给PInvoke Interop Assistant

编辑:我试图解决的实际问题

.net c# pinvoke unmanaged function-signature

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

从C#访问COM对象的最佳方法

我打算使用作为COM对象公开的各种对象.为了使它们更容易使用,我想将它们包装为C#对象.对此最好的方法是什么?

.net c# com pinvoke

33
推荐指数
3
解决办法
5万
查看次数

C#:如何将null传递给期望ref的函数?

我有以下功能:

public static extern uint FILES_GetMemoryMapping(
    [MarshalAs(UnmanagedType.LPStr)] string pPathFile,
    out ushort Size,
    [MarshalAs(UnmanagedType.LPStr)] string MapName,
    out ushort PacketSize,
    ref Mapping oMapping,
    out byte PagesPerSector);
Run Code Online (Sandbox Code Playgroud)

我想这样称呼:

FILES_GetMemoryMapping(MapFile, out size, MapName,
    out PacketSize, null, out PagePerSector);
Run Code Online (Sandbox Code Playgroud)

不幸的是,我无法传递null一个需要类型的字段ref Mapping而且没有投射我已经尝试修复此问题.

有什么建议?

c# parameters null pinvoke ref

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

如何从Native(C++)代码返回文本

我使用Pinvoke实现本机(C++)代码和托管(C#)代码之间的互操作性.我想要实现的是从本机代码中获取一些文本到我的托管代码中.为此,我尝试了很多东西,例如通过ref传递字符串/ stringbuilder,使用[IN]和[OUT],Marshaling到LPSTR,从函数返回字符串等,但在我的情况下没有任何作用.任何有关一些小代码的帮助都将受到高度赞赏.

c# c++ string pinvoke

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