- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个第 3 方 C 库,其导出方法之一如下:
#define MAX_INDEX 8
int GetStuff(IN char* index[MAX_INDEX], OUT char* buf, IN size_t size);
第一个参数用指向存储特定字符串的 buf 参数的指针填充。大小表示每个字符串预计在 buf 缓冲区中的长度。我的 C# P/Invoke 方法目前看起来像这样:
[DllImport("Path/To/Dll", CharSet = CharSet.Ansi)]
private static extern int GetStuff(IntPtr indecies, IntPtr buf, Int32 size);
C# P/Invoke 方法是私有(private)的,因为我将它的功能包装在一个公共(public)的“getter”方法中,该方法为调用者处理内存的分配/解除分配。当我在 C++ 中使用此方法时,迭代实际上非常简单。我只是做类似的事情:
char* pIndecies[MAX_INDEX];
char* pBuffer = new char[MAX_INDEX * (256 + 1)]; // +1 for terminating NULL
GetStuff(pIndecies, pBuffer, 256);
// iterate over the items
for(int i(0); i < MAX_INDEX; i++) {
if(pIndecies[i]) {
std::cout << "String for index: " << i << " " << pIndecies[i] << std::endl;
}
}
由于这些在 C++ 中的使用方式,我决定我可能应该使用 IntPtr 对象并仅从堆中分配我需要的内存,调用 native 代码,然后像在 C++ 中那样对其进行迭代.然后我想起了 C# 中的字符是 unicode 字符而不是 ASCII 字符。即使我将迭代放在不安全的代码块中,C# 中的迭代是否也能正常工作?我的第一个想法是执行以下操作:
IntPtr pIndecies = Marshal.AllocHGlobal(MAX_INDEX * 4); // the size of a 32-pointer
IntPtr pBuffer = Marshal.AllocHGlobal(MAX_INDEX * (256 + 1)); // should be the same
NativeMethods.GetStuff(pIndecies, pBuffer, 256);
unsafe {
char* pCStrings = (char*)pIndecies.ToPointer();
for(int i = 0; i < MAX_INDEX; i++) {
if(pCStrings[i])
string s = pCStrings[i];
}
}
然后我的问题是,“我应该如何迭代这个 native 代码方法返回的内容?”这是编码此功能的正确方法吗?我应该为第二个参数使用 StringBuilder 对象吗?一个限制性问题是第一个参数是 GetStuff() 方法后面的结构的 1:1 映射。每个索引的值对于理解您在第二个缓冲区参数中查看的内容至关重要。
我很感激任何建议。
谢谢,安迪
最佳答案
我认为您走在正确的轨道上,但我会在不使用不安全代码的情况下做到这一点。像这样:
[DllImport("Path/To/Dll", CharSet = CharSet.Ansi)]
private static extern int GetStuff(IntPtr[] index, IntPtr buf, Int32 size);
....
IntPtr[] index = new IntPtr[MAX_INDEX];
IntPtr pBuffer = Marshal.AllocHGlobal(MAX_INDEX * 256 + 1);
try
{
int res = NativeMethods.GetStuff(index, pBuffer, 256);
// check res for errors?
foreach (IntPtr item in index)
{
if (item != IntPtr.Zero)
string s = Marshal.PtrToStrAnsi(item);
}
}
finally
{
Marshal.FreeHGlobal(pBuffer);
}
这是对您的 C++ 版本的非常直接的翻译。
关于c# - 遍历使用 Marshal.AllocHGlobal() 分配的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9981626/
在编程环境中是哪一个?有区别吗?我已经看到了这两种方式,我不想在我的代码中拼错它。 最佳答案 编码(marshal)是工作图 block ;例如,消防编码(marshal)或美国编码(marshal)
我有以下结构: [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct WAVEHDR { in
我找不到以下问题的明确答案:如果一个 COM 类是线程安全的,即它被标记为 Both 或 Free,我真的需要编码它的对象接口(interface)以将它传递给另一个线程吗?相同的过程?我不问两个线程
在编译 C# ASP.NET 应用程序时,我从 Visual Studio 2008 中收到奇怪的警告。谁能告诉我这个警告的含义(如果可能的话,用几个音节的词)? At least one of th
TL;DR:MongoDB 驱动程序是否提供了编码和解码文档单个字段的功能? 这是一个非常简单的问题,但这里有一些上下文: 我有一个工作人员负责在 2 个独立的数据库之间同步数据。当它接收到事件消息时
是否可以在使用自定义编码(marshal)拆收器的结构上使用 Marshal.SizeOf()? 例如: struct Abcde { public int test1; [MarshalAs
我有一张 map :[]map[string]string . 将结果填充到 json.marshal()兼容的对象。输出: [ { "key1": "val1", "key2":
如何在没有根元素的情况下进行编码(marshal)? type Ids struct { Id []string `xml:"id"` } IdsStr, _ := xml.Marshal(&Id
我有这个 C++ 代码: extern "C" __declspec(dllexport) VOID AllocateFoo(MY_DATA_STRUCTURE** foo) { *foo =
我创建了 map[string]interface{} 并且我想通过 2 个重置服务之间的映射传递多种类型。 每次我编码时,我都会在应该包含 reflect.Type 的字段中得到空映射。 Servi
我有一个托管的 .Net 类,它创建了我需要确保正确清理的非托管资源。 我有一个顺序结构: [StructLayout(LayoutKind.Sequential)] struct FooBar {
我在用 val akkaV = "2.2.3" val sprayV = "1.2.0" Seq( "io.spray" % "spray-can" % spra
我正在使用 Castor 编码/取消编码我的 Java 对象,其中一个对象包含一个 EnumMap。Castor 可以编码(marshal)/解封 EnumMaps 吗?我有一个带有一些嵌套 Hash
错误:com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMappingException:无法编码类型类 [Ljava.lang.Strin
我们在 netbeans 中做了一次 cleanbuild,检查了 jdk 版本并在服务器上部署了所有内容,但仍然出现以下错误。有人可以帮忙吗? javax.servlet.ServletExcept
我想知道是否可以对我的类进行注释,以便编码器第一次遇到对象时,它会生成适当类型的 XML 元素,但任何其他对该对象的后续引用都将具有 XML IDREF条目已创建? 最佳答案 您可以利用 JAXB 的
我正在从现有代码构建一个通用类库,但我收到了一些编译器警告,提示我终其一生都不知道该如何处理。 我有这样的代码: void SomeMethod(Object data) { var size =
我在编码我的 JAXBElement 时遇到了这个异常,它有几个子元素。我如何弄清楚如何查明导致此异常的子元素? java.lang.NullPointerException at com.s
本文整理了Java中org.apache.poi.openxml4j.opc.internal.marshallers.ZipPartMarshaller.marshall()方法的一些代码示例,展示
我最近已经问了一个有关 JAXB 的问题,可以在以下位置找到:How to marshal/unmarshal Java objects with private fields using JAXB
我是一名优秀的程序员,十分优秀!