标签: pinvoke

使用P/Invoke编组结构时,如何忽略字段

我想编组一个与P/Invoke一起使用的结构,但是这个结构包含一个只与我的托管代码相关的字段,因此我不希望它被编组,因为它不属于本机结构.它甚至可能吗?我正在寻找类似于NonSerialized序列化的属性,但它似乎不存在......

struct MyStructure
{
    int foo;
    int bar;

    [NotMarshaled] // This attribute doesn't exist, but that's the kind of thing I'm looking for...
    int ignored;
}
Run Code Online (Sandbox Code Playgroud)

任何建议将不胜感激

.net pinvoke structure ignore marshalling

11
推荐指数
1
解决办法
4551
查看次数

P/Invoke,c#:unsigned char丢失一个字节

我正在努力为软件SDK的DLL文件,我试图调用一个函数来获取有关软件主机的信息.

在函数想要的结构中有两个unsigned char变量(HostMachineAddress,HostProgramVersion),当我尝试从c#调用它时,我似乎"松散"了最后一个字节...如果我将下面的c#struct中的SizeConst更改为5我确实得到了丢失的字节,但是它导致另一个变量丢失了数据.

有人可以帮我找到解决这个问题的方法吗?也尝试使用类而不是struct导致system.stackoverflow错误

C#Struct

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct sHostInfo
{
    public int bFoundHost;
    public int LatestConfirmationTime;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
    public string szHostMachineName;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
    public string HostMachineAddress;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
    public string szHostProgramName;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
    public string HostProgramVersion;
}
Run Code Online (Sandbox Code Playgroud)

C#

[DllImport("Cortex_SDK.dll")]
public static extern int GetHostInfo(out sHostInfo pHostInfo);
Run Code Online (Sandbox Code Playgroud)

c# pinvoke marshalling unsigned-char

11
推荐指数
1
解决办法
1027
查看次数

.Net框架中是否存在系统错误代码的枚举?

我有一个库函数返回GetLastError代码(像这样的东西).我需要将它们与特定的错误进行比较,比如ERROR_INVALID_HANDLE.但是我自己定义常量并不舒服.所以问题是,为此目的是否有预定义的枚举?

.net pinvoke

11
推荐指数
2
解决办法
3012
查看次数

我可以强制MSTest为每次测试运行使用新进程吗?

我们正在使用VS 2010测试运行器(MSTest)进行自动功能测试.当我们从Visual Studio运行测试时,VS会创建一个名为QTAgent32.exe的进程,并在该进程中运行测试.

我们发现当我们进行多次测试运行时,MSTest将重用相同的QTAgent32进程 - 进程ID不会改变.这对我们来说是一个问题,因为我们正在测试的代码是P /调用非托管DLL.DLL需要在进程的生命周期内初始化一次.我们有一个[AssemblyInitialize]方法,但每次测试运行一次.如果我们执行多次测试运行,它将在同一进程中执行多次.

每次我们进行测试运行时,MSTest都会创建一个新的appdomain; 但这些appdomains都在同一个过程中.

所以我想知道:有没有办法告诉Visual Studio测试运行器每次运行测试时都使用新进程?我查看了".testsettings"配置,但没有看到任何相关内容.

.net pinvoke mstest visual-studio

11
推荐指数
1
解决办法
3257
查看次数

如何正确定义PRINT_NOTIFY_INFO_DATA?

我正在玩codeproject的一个项目,它基本上监视计算机上的打印活动.但是,对于64位配置,它无法正常工作.代码的下面部分是问题.打印完成后,将调用此代码.

PRINTER_NOTIFY_INFO info = (PRINTER_NOTIFY_INFO)Marshal.PtrToStructure(pNotifyInfo, typeof(PRINTER_NOTIFY_INFO));                        
int pData = (int)pNotifyInfo + Marshal.SizeOf(typeof(PRINTER_NOTIFY_INFO));
PRINTER_NOTIFY_INFO_DATA[] data = new PRINTER_NOTIFY_INFO_DATA[info.Count];
for (uint i = 0; i < info.Count; i++)
{
    data[i] = (PRINTER_NOTIFY_INFO_DATA)Marshal.PtrToStructure((IntPtr)pData, typeof(PRINTER_NOTIFY_INFO_DATA));
    pData += Marshal.SizeOf(typeof(PRINTER_NOTIFY_INFO_DATA));
}
Run Code Online (Sandbox Code Playgroud)

调试显示数据[i] .field值始终为0.但在32位中它可以正常工作.我认为没有正确定义PRINTER_NOTIFY_INFO_DATA.目前我正在使用以下代码.任何人都可以解决这个问题,以便在64位中正常工作吗?

[StructLayout(LayoutKind.Sequential)]
public struct PRINTER_NOTIFY_INFO
{
    public uint Version;
    public uint Flags;
    public uint Count;
}


[StructLayout(LayoutKind.Sequential)]
public struct PRINTER_NOTIFY_INFO_DATA_DATA
{
    public uint cbBuf;
    public IntPtr pBuf;
}

[StructLayout(LayoutKind.Explicit)]
public struct PRINTER_NOTIFY_INFO_DATA_UNION
{
    [FieldOffset(0)]
    private uint adwData0;
    [FieldOffset(4)]
    private uint adwData1;
    [FieldOffset(0)]
    public PRINTER_NOTIFY_INFO_DATA_DATA …
Run Code Online (Sandbox Code Playgroud)

c# pinvoke interop

11
推荐指数
1
解决办法
1789
查看次数

P/Invoke [In,Out]属性是否可选用于编组数组?

假设存在一个带有纯C接口的本机函数,如下所示,从本机DLL导出:

// NativeDll.cpp

extern "C" void __stdcall FillArray(
    int fillValue, 
    int count, 
    int* data)
{
    // Assume parameters are OK...

    // Fill the array
    for (int i = 0; i < count; i++)
    {
        data[i] = fillValue;
    }
}
Run Code Online (Sandbox Code Playgroud)

以下P/Invoke工作正常(使用VS2010 SP1测试):

[DllImport("NativeDll.dll", CallingConvention=CallingConvention.StdCall)]
public static extern void FillArray(
    int fillValue,
    int count,
    [In, Out] int[] data
);
Run Code Online (Sandbox Code Playgroud)

以及这个P /调用,与上面相同,但没有[In, Out]属性:

[DllImport("NativeDll.dll", CallingConvention=CallingConvention.StdCall)]
public static extern void FillArray(
    int fillValue,
    int count,
    int[] data
);
Run Code Online (Sandbox Code Playgroud)

那么,这些 …

c# c++ arrays pinvoke attributes

11
推荐指数
1
解决办法
4263
查看次数

DllImport如何真正起作用?

我想知道它是如何DllImport工作的.我需要一个简单的英语解释 - 意思是简单的解释.

它是否与DLL中的导出方法静态链接,如"包含文件"指令/静态库?

或者当它到达C#程序中的执行点时,它是否从DLL动态调用该方法?

c# dll pinvoke dllimport

11
推荐指数
2
解决办法
3053
查看次数

结构中C#fixed bool数组的大小和对齐是什么?

在进行P/Invoke时,重要的是使数据布局匹配.

我们可以使用一些属性来控制struct的布局.

例如:

struct MyStruct 
{
    public bool f;
}
Run Code Online (Sandbox Code Playgroud)

给出大小为4.虽然我们可以告诉编译器使它成为1字节bool以匹配C++类型bool:

struct MyStruct
{
    [MarshalAs(UnmanagedType.I1)]
    public bool f;
}
Run Code Online (Sandbox Code Playgroud)

给出1的大小.

这些都有道理.但是当我测试固定的bool阵列时,我很困惑.

unsafe struct MyStruct
{
    public fixed bool fs[1];
}
Run Code Online (Sandbox Code Playgroud)

给出4个字节的大小.和

unsafe struct MyStruct
{
    public fixed bool fs[4];
}
Run Code Online (Sandbox Code Playgroud)

仍然给出4个字节的大小.但

unsafe struct MyStruct
{
    public fixed bool fs[5];
}
Run Code Online (Sandbox Code Playgroud)

给出8的大小.

它看起来像在固定的bool数组中,bool元素的大小仍然是1个字节,但是对齐是4个字节.这与C++ bool数组不匹配,后者是1字节大小和对齐方式.

有人能解释一下吗?

更新:我终于找到了,原因是,bool类型在一个结构中,那么该结构永远不会是blittable!因此,不要指望内部具有bool类型的结构与C中的布局相同.

问候,翔.

c# pinvoke

11
推荐指数
1
解决办法
872
查看次数

在调用Windows API时,CLR如何比我更快

当我发现令人惊讶的事情(对我而言)时,我测试了生成时间戳的不同方法.

GetSystemTimeAsFileTime使用P/Invoke 调用Windows 比调用DateTime.UtcNow内部使用CLR的包装器的速度快3倍GetSystemTimeAsFileTime.

怎么可能?

DateTime.UtcNow是实施:

public static DateTime UtcNow {
    get {
        long ticks = 0;
        ticks = GetSystemTimeAsFileTime();
        return new DateTime( ((UInt64)(ticks + FileTimeOffset)) | KindUtc);
    }
}

[MethodImplAttribute(MethodImplOptions.InternalCall)] // Implemented by the CLR
internal static extern long GetSystemTimeAsFileTime();
Run Code Online (Sandbox Code Playgroud)

核心CLR的包装GetSystemTimeAsFileTime:

FCIMPL0(INT64, SystemNative::__GetSystemTimeAsFileTime)
{
    FCALL_CONTRACT;

    INT64 timestamp;

    ::GetSystemTimeAsFileTime((FILETIME*)&timestamp);

#if BIGENDIAN
    timestamp = (INT64)(((UINT64)timestamp >> 32) | ((UINT64)timestamp << 32));
#endif

    return timestamp;
}
FCIMPLEND;
Run Code Online (Sandbox Code Playgroud)

我的测试代码使用BenchmarkDotNet:

public …
Run Code Online (Sandbox Code Playgroud)

.net c# clr performance pinvoke

11
推荐指数
2
解决办法
634
查看次数

使用Linux在.net核心中调用P-Invoke

有没有办法(dllimport)在Linux上的.NET Core中实现P/Invoke ?

示例:

我用.net框架编译了C++ MyLib.dll.

如果可以这样使用,或者不支持使用.net-core使用linux调用native win api?

[DllImport("MyLib.dll", CallingConvention = CallingConvention.StdCall)]
internal static extern long NativeMethod();
Run Code Online (Sandbox Code Playgroud)

pinvoke .net-core

11
推荐指数
2
解决办法
8539
查看次数