我有一个接受一个结构的DLL,该结构包含一个指向函数的指针来进行回调.
如何将IntPtr作为我的应用程序的函数来构建结构?
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class OPERATION {
public uint OperationID;
public IntPtr Context;
public IntPtr Callback; -> How to pass this?
}
Run Code Online (Sandbox Code Playgroud)
这是委托接受OPERATION结构
public delegate void MY_CALLBACK([In] OPERATION operation, [In] uint msgId, [In] IntPtr msgDataPtr);
Run Code Online (Sandbox Code Playgroud) 可能重复:
如何从C#中的byte []获取IntPtr
我正在从记忆中读取字符串
byte[] array =
reader.ReadProcessMemory((IntPtr)address, (uint)255, out bytesReadSize);
Run Code Online (Sandbox Code Playgroud)
然后我将这个数组转换为字符串.
我现在遇到一个问题,因为程序内存中的地址003A53D4有一个指向字符串的指针.我怎样才能得到字符串的地址?谢谢 :)
那是我做了什么:
IntPtr pointers_address = new IntPtr(module_base_address + 3822548);
byte[] pointer_arrays =
reader.ReadProcessMemory(pointers_address, (uint)16, out bytesReadSize2);
IntPtr pointer_for_string = new IntPtr();
Marshal.Copy(pointers_array, 0, pointer_for_string, 16);
Run Code Online (Sandbox Code Playgroud)
它说(约4行):
值不能为空.参数名称:destination
当我将新的IntPtr()更改 为新的IntPtr(1)时, 它说
尝试读取或写入受保护的内存.这通常表明其他内存已损坏.
我只是看一个例子,在其中我看到了代码
return new IntPtr(handle);
Run Code Online (Sandbox Code Playgroud)
在探索我们的代码之后,我发现我们已经使用了类似的模式,但在我们的代码中我们几乎有相同的东西:
return (IntPtr)handle;
Run Code Online (Sandbox Code Playgroud)
这两种情况有区别吗?第二个是否会以任何方式"更好",因为它不会分配新的内存,或者只是隐藏相同的构造函数?
我从我看到的一个例子中做到了这一点,它从未抛出任何错误,但图像显示为灰色.
有一个更好的方法吗?
private unsafe void menuItem7_Click(object sender, EventArgs e)
{
var settings = Utility.GatherLocalSettings();
openFileDialog1.InitialDirectory = settings.SavePath;
openFileDialog1.Filter = "Scan Files (*.jpg)|*.jpg";
openFileDialog1.FilterIndex = 1;
openFileDialog1.RestoreDirectory = true;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
byte[] openFile = File.ReadAllBytes(openFileDialog1.FileName);
fixed (byte* p = openFile)
{
IntPtr img = (IntPtr)p;
frmContainer newScan = new frmContainer(img);
newScan.MdiParent = this;
newScan.Text = Path.GetFileName(openFileDialog1.FileName) + " [Saved]";
newScan.Show();
}
}
}
Run Code Online (Sandbox Code Playgroud)
PS:我检查了csproj以允许构建中的不安全代码.
假设我有以下签名:
static extern void External(int foo, IntPtr bar);
Run Code Online (Sandbox Code Playgroud)
我想让它使用默认值:
static extern void External(int foo = 10, IntPtr bar = default(IntPtr));
Run Code Online (Sandbox Code Playgroud)
这有效吗?在C++中,我会使用指针为0或null.在C#中,IntPtr是值还是引用甚至都不清楚.
如果我手动调用我的函数,我会使用External(10, IntPtr.Zero);.我想我的问题是:default(IntPtr)会有同样的行为IntPtr.Zero吗?
如何使用Emgu cv CvInvoke.cvLoadImage(...)从特定文件夹加载图像?我试着这样做
IntPtr inputImage = CvInvoke.cvLoadImage("C:\\Users\\...\\ClassPic1.jpg");
Run Code Online (Sandbox Code Playgroud)
这可以吗?如果是这样,我将如何作为Emgu.CV.Image文件访问它,以便我将对其进行图像处理?
我有一个类定义如下:
[StructLayout(LayoutKind.Sequential)]
public class OUR_MEM_STR
{
public byte[] p;
public int len;
};
Run Code Online (Sandbox Code Playgroud)
这是以下 C 结构的等效定义:
typedef struct
{
void *p;
int len;
} OUR_MEM_STR;
Run Code Online (Sandbox Code Playgroud)
我使用 byte[] 而不是 IntPtr 类型作为成员 p 因为它在整个 c# 项目中的使用方式。
我用 len = 10 和 p = new byte[10] 定义了一个对象 obj
我想让它成为一个intptr。我如何获得对象的大小?
IntPtr pObj = Marshal.AllocHGlobal(obj.len + sizeof(int));
Marshal.StructureToPtr(obj, pObj, true);
Run Code Online (Sandbox Code Playgroud)
看看我在那里做了什么。它似乎太硬编码。如果我执行以下代码段;
IntPtr pObj = Marshal.AllocHGlobal(Marshal.SizeOf(obj));
Run Code Online (Sandbox Code Playgroud)
这样做会返回错误的大小,因为 obj.p 返回的大小是 4 而不是 10。因为指向字节数组的指针占用的内存是 4 字节。
有没有更好的办法?
我在C#中使用一个包装的C库,需要将该库中的图像转换为Bitmap并返回,但不复制像素缓冲区.
转换为位图很简单:
Bitmap WrapAsBitmap(CImage image)
{
return new Bitmap(image.Width, image.Height, image.BytesPerLine, PixelFormat.Format24bppRgb, image.Data);
}
Run Code Online (Sandbox Code Playgroud)
只需将原始像素buffer(image.Data)传递给Bitmap构造函数,就不需要复制.为了做相反的事情,我需要调用LockBits并UnlockBits访问IntPtr原始像素缓冲区:
CImage WrapAsCImage(Bitmap bitmap)
{
BitmapData data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
var image = new CImage(bitmap.Width, bitmap.Height, data.Stride * 3, data.Scan0);
bitmap.UnlockBits(data);
return image;
}
Run Code Online (Sandbox Code Playgroud)
现在,正如您所看到的,如果data.Scan0是在托管内存中,这实际上是一种危险的方法,因为在使用新构造之前,这些位是"未锁定的" image.如果bitmap是从该WrapAsBitmap方法构造的,那么data.Scan0指向不受.NET移动的非托管内存就没有问题.因此,我想构建一个安全检查,检查data.Scan0指针的位置(托管/非托管).
另一个解决方法我想的是从继承Bitmap类,并跟踪到原始指针image.Data与一起Bitmap,但Bitmap类是密封的,所以我的运气.
简而言之:任何想法如何检测一个位置(托管/非托管)IntPtr …
我有一个文本框,我想输入(手动)一个句柄(http://i.imgur.com/S1bCyPy.png)
我的问题:要从文本框中获取值,我需要这样做:
textBoxHandle.Text;
Run Code Online (Sandbox Code Playgroud)
但是当我将我的Handle初始化为IntPtr(句柄)时,这不起作用:
IntPtr h = new IntPtr(textBoxHandle.Text);
Run Code Online (Sandbox Code Playgroud)
我试过了
(IntPtr) textBoxHandle.Text
Run Code Online (Sandbox Code Playgroud)
还有我在这里读过的许多其他选项,如Marshal.StringToHGlobalAnsi方法,但它们不起作用/它们改变了内容.
我的问题:如何从文本框中的字符串(使用句柄格式)获取IntPtr(句柄)?
编辑:在文本框中,我会写0x00040C66.
最终的代码应该是:
IntPtr hWnd = new IntPtr(0x00040C66);
Run Code Online (Sandbox Code Playgroud)
但是从文本框中更改IntPtr的值.
编辑:我的问题被标记为重复(如何将非托管IntPtr类型转换为ac#string?)但它不一样.它不是从IntPtr到String我想要的.我需要相反的,从String到IntPtr.