标签: intptr

IntPtr算术

我试图以这种方式分配一个结构数组:

struct T {
    int a; int b;
}

data = Marshal.AllocHGlobal(count*Marshal.SizeOf(typeof(T));
...
Run Code Online (Sandbox Code Playgroud)

我想访问分配的数据"绑定"一个结构到分配给AllocHGlobal的数组中的每个元素...像这样的东西

T v;
v = (T)Marshal.PtrToStructure(data+1, typeof(T));
Run Code Online (Sandbox Code Playgroud)

但我没有找到任何方便的方法... 为什么IntPtr缺乏算术?我该如何以"安全"的方式解决这个问题?

有人可以确认PtrToStructure函数将数据复制到struct变量中吗?换句话说,修改结构体是否反映了结构数组数据中的修改?

当然,我想对使用struct的IntPtr指向的数据进行操作,而不是每次都复制数据,避免使用不安全的代码.

谢谢大家!

c# marshalling intptr

7
推荐指数
2
解决办法
4625
查看次数

gdip image直接在我的本地驱动器中保存intptr

我有这段代码从扫描仪获取图像文件并将其保存在本地磁盘上:

                            IntPtr img = (IntPtr)pics[i];
                            SetStyle(ControlStyles.DoubleBuffer, false);
                            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
                            SetStyle(ControlStyles.Opaque, true);
                            SetStyle(ControlStyles.ResizeRedraw, true);
                            SetStyle(ControlStyles.UserPaint, true);
                            bmprect = new Rectangle(0, 0, 0, 0);
                            bmpptr = GlobalLock(img);
                            pixptr = GetPixelInfo(bmpptr);
                            Gdip.SaveDIBAs(@"C:\", bmpptr, pixptr);
Run Code Online (Sandbox Code Playgroud)

问题出在这里Gdip.SaveDIBAs(@"C:\", bmpptr, pixptr);.保存对话框. 在此输入图像描述

我想丢弃此对话框并将文件直接保存在我的驱动器中.

**Updated:**



  public static bool SaveDIBAs(string picname, IntPtr bminfo, IntPtr pixdat)
        {
            SaveFileDialog sd = new SaveFileDialog();

            sd.FileName = picname;
            sd.Title = "Save bitmap as...";
            sd.Filter =
                "Bitmap file (*.bmp)|*.bmp|TIFF file (*.tif)|*.tif|JPEG file (*.jpg)|*.jpg|PNG file (*.png)|*.png|GIF file (*.gif)|*.gif|All files (*.*)|*.*";
            sd.FilterIndex = 1;

            return …
Run Code Online (Sandbox Code Playgroud)

c# image scanning intptr save-dialog

7
推荐指数
1
解决办法
467
查看次数

如何在C#中编组int*?

我想在非托管库中调用此方法:

void __stdcall GetConstraints(

  unsigned int* puiMaxWidth,

  unsigned int* puiMaxHeight,

  unsigned int* puiMaxBoxes

);
Run Code Online (Sandbox Code Playgroud)

我的解决方案

  • 代表定义:

    [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate void GetConstraintsDel(UIntPtr puiMaxWidth,UIntPtr puiMaxHeight,UIntPtr puiMaxBoxes);

  • 方法的调用:

    // PLUGIN NAME
    GetConstraintsDel getConstraints = (GetConstraintsDel)Marshal.GetDelegateForFunctionPointer(pAddressOfFunctionToCall, typeof(GetConstraintsDel));
    
     uint maxWidth, maxHeight, maxBoxes;
    
     unsafe
     {
        UIntPtr a = new UIntPtr(&maxWidth);
        UIntPtr b = new UIntPtr(&maxHeight);
        UIntPtr c = new UIntPtr(&maxBoxes);
        getConstraints(a, b, c);
     }
    
    Run Code Online (Sandbox Code Playgroud)

它有效,但我必须允许"不安全"的标志.有没有不安全代码的解决方案?或者这个解决方案好吗?我不太明白用不安全标志设置项目的含义.

感谢帮助!

.net marshalling intptr

6
推荐指数
1
解决办法
4327
查看次数

IntPtr到字节数组和返回

引用如何从C#中的byte []获取IntPtr

我试图读取IntPtr引用到byte []然后再返回另一个IntPtr的数据.指针正在引用从扫描仪设备捕获的图像,因此我还假设捕获此信息应放入字节数组中.

我也不确定Marshal.SizeOf()方法是否会返回IntPtr引用的数据大小或指针本身的大小.

我的问题是我收到错误"类型'System.Byte []'不能被编组为非托管结构;没有有意义的大小或偏移量可以计算"

IntPtr bmpptr = Twain.GlobalLock (hImage);

try
{
     byte[] _imageTemp = new byte[Marshal.SizeOf(bmpptr)];
     Marshal.Copy(bmpptr, _imageTemp, 0, Marshal.SizeOf(bmpptr));

     IntPtr unmanagedPointer = Marshal.AllocHGlobal(
         Marshal.SizeOf(_imageTemp));

     try
     {
           Marshal.Copy(_imageTemp, 0, unmanagedPointer, 
               Marshal.SizeOf(_imageTemp));

           Gdip.SaveDIBAs(
               string.Format("{0}\\{1}.{2}", CaptureFolder, "Test", "jpg"), 
               unmanagedPointer, false);
     }
     finally
     {
           Marshal.FreeHGlobal(unmanagedPointer);
     }
}
catch (Exception e)
{
      Scanner.control.Test = e.Message;
}
Run Code Online (Sandbox Code Playgroud)

c# interop marshalling intptr

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

为什么我们不能在C#中进行IntPtr和UIntPtr算术?

这是一个看起来很简单的问题:

鉴于本地大小的整数是最好的算法,为什么不C#(或任何其他.NET语言)支持算术与本地大小IntPtrUIntPtr

理想情况下,您可以编写如下代码:

for (IntPtr i = 1; i < arr.Length; i += 2) //arr.Length should also return IntPtr
{
    arr[i - 1] += arr[i]; //something random like this
}
Run Code Online (Sandbox Code Playgroud)

这样它就可以在32位和64位平台上运行.(目前,您必须使用long.)


编辑:

没有使用它们作为指针(甚至没有提到"指针"这个词)!它们可以被视为native intMSIL和intptr_tC中的C#对应物stdint.h- 它们是整数,而不是指针.

.net c# intptr

6
推荐指数
2
解决办法
1406
查看次数

为什么不能比较IntPtr.Zero和默认(IntPtr)?

我刚刚学会了IntPtr.Zero无法与默认(IntPtr)进行比较的困难方法.有人可以告诉我为什么吗?

IntPtr.Zero == new IntPtr(0) -> "could not evaluate expression"
IntPtr.Zero == default(IntPtr) --> "could not evaluate expression"
IntPtr.Zero == (IntPtr)0 -> "could not evaluate expression"

IntPtr.Zero.Equals(IntPtr.Zero) --> "Enum value was out of legal range" exception
IntPtr.Zero.Equals(default(IntPtr)) --> "Enum value was out of legal range" exception

IntPtr.Zero == IntPtr.Zero --> true
new IntPtr(0) == new IntPtr(0) --> true
Run Code Online (Sandbox Code Playgroud)

.net c# default intptr

6
推荐指数
1
解决办法
1194
查看次数

Marshal.Copy,将一个 IntPtr 数组复制到一个 IntPtr 中

我无法弄清楚该Copy(IntPtr[], Int32, IntPtr, Int32)方法是如何工作的。我虽然它可以将包含在多个 IntPtr 中的数据复制到单个 IntPtr(如 MSDN 所述)但显然它不像我预期的那样工作:

IntPtr[] ptrArray = new IntPtr[]
{
    Marshal.AllocHGlobal(1),
    Marshal.AllocHGlobal(2)
 };

 Marshal.WriteByte(ptrArray[0], 0, 0xC1);

 // Allocate the total size.
 IntPtr ptr = Marshal.AllocHGlobal(3);

 Marshal.Copy(ptrArray, 0, ptr, ptrArray.Length);

 // I expect to read 0xC1 but Value is always random!!
 byte value = Marshal.ReadByte(ptr, 0);
Run Code Online (Sandbox Code Playgroud)

有人知道我是否将这种方法用于不是它的目的吗?

c# arrays copy marshalling intptr

6
推荐指数
1
解决办法
9743
查看次数

PostMessage 无法传递字符串 C#

这是我的原型:

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern bool PostMessage(int hhwnd, uint msg, IntPtr wparam, IntPtr lparam);
Run Code Online (Sandbox Code Playgroud)

这是我如何使用它:

PostMessage(HWND_BROADCAST, msg, Marshal.StringToHGlobalAuto("bob"), IntPtr.Zero);
Run Code Online (Sandbox Code Playgroud)

在另一个线程中,我可以截获此消息,但是当我尝试使用以下方法取回 bob 时:

string str = Marshal.PtrToStringAuto(m.WParam); // where m = the Message object
Run Code Online (Sandbox Code Playgroud)

我没有得到鲍勃在 str。

我认为这一定是因为我在一个线程的堆栈上引用了“bob”字符串,而该引用在另一个线程的堆栈中绝对没有意义。但如果是这样的话,这些 wparam 和 lparam 指针真的只用于在同一线程中传递的消息吗?

编辑*更正:通过线程我的意思是进程。这是在进程之间传递字符串而不是线程的问题。

c# parameters postmessage intptr

5
推荐指数
1
解决办法
6363
查看次数

IntPtr并避免使用不安全的代码

我有一个采用IntPtr的外部库。有没有安全的方法可以做到这一点...

int BytesWritten = 0;
Output.WriteBytes(buffer, new IntPtr(&BytesWritten));
Run Code Online (Sandbox Code Playgroud)

...而不必使用“不安全”代码?我对IntPtrs不太熟悉,但是我想做这样的事情:

fixed int BytesWritten = 0;
Output.WriteBytes(buffer, IntPtr.GetSafeIntPtr(ref BytesWritten));
Run Code Online (Sandbox Code Playgroud)

...以这种方式,我不需要使用/ unsafe进行编译。

我不能更改WriteBytes函数,它是一个外部函数。

似乎在'ref int'和IntPtr之间应该进行某种类型的转换,但是我还没有找到它的运气。

.net c# intptr

5
推荐指数
1
解决办法
2460
查看次数

C# out IntPtr 在 Java 中等效

我在 C# 中有一个从 .dll 调用的方法

[DllImport("somedll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int find([MarshalAs(UnmanagedType.AnsiBStr, SizeConst = 64)] string atr, out IntPtr int);

[DllImport("somedll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int getData(IntPtr int, int dataId, byte[] dataBuffer, ref int dataBufferSize);
Run Code Online (Sandbox Code Playgroud)

在 C# 中调用这个方法看起来像这样

static IntPtr number = IntPtr.Zero;
static int res = 0;
try{
    number = IntPtr.Zero;
    res = find(null, out number);   
    if (number == IntPtr.Zero)
                throw new ApplicationException("Something is wrong");
    uint dataBufferSize = 1024;
    res = getData(number, 1, null, ref …
Run Code Online (Sandbox Code Playgroud)

java pointers jna intptr

5
推荐指数
1
解决办法
2690
查看次数