P/调用传递给 StringBuilder 的函数
在 C# 文件中,我有一个
class Archiver {
[DllImport("Archiver.dll")]
public static extern void archive(string data, StringBuilder response);
}
字符串数据作为输入,StringBuilder 响应是函数写入内容的地方,
存档函数原型(用 C 编写)如下所示:
void archive(char * dataChr, char * outChr);
它接收 dataChr 中的字符串,然后
strcpy(outChr,"some big text");
从 C# i 执行 a称之为这样的东西:
string message = "some text here";
StringBuilder response = new StringBuilder(10000);
Archiver.archive(message,response);
这可行,但问题是,正如您可能看到的那样,我为 StringBuilder 大小赋予了一个值,但存档函数可能会返回一个比我给我的大小更大的文本字符串生成器。有办法解决这个问题吗?
in a C# file i have a
class Archiver {
[DllImport("Archiver.dll")]
public static extern void archive(string data, StringBuilder response);
}
string data is an input, and StringBuilder response is where the function writes something
the archive function prototype (written in C) looks like this:
void archive(char * dataChr, char * outChr);
and it receives a string in dataChr, and then does a
strcpy(outChr,"some big text");
from C# i call it something like this:
string message = "some text here";
StringBuilder response = new StringBuilder(10000);
Archiver.archive(message,response);
this works, but the problem, as you might see is that i give a value to the StringBuilder size, but the archive function might give back a (way) larger text than the size i've given to my StringBuilder. any way to fix this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您需要编写一个函数来告诉您 StringBuilder 需要有多大,然后调用该函数来初始化 StringBuilder。
You need to write a function that tells you how big the
StringBuilder
needs to be, then call that function to initialize theStringBuilder
.您是否控制
archive
功能的实现?如果您这样做,那么您有几个选择。1- 让
archive
函数分配缓冲区并将其返回给调用者。缺点是调用者需要使用正确的函数来释放缓冲区,否则可能会导致内存泄漏甚至损坏堆。2- 将缓冲区的大小传递给
archive
函数,以便填充缓冲区时不会超过缓冲区长度。3-如果您可以有一个可以返回所需缓冲区大小的函数,那么您可以使用它。这是 Windows API 中的常见方法,传递
null
作为缓冲区和指向接收所需缓冲区大小的 DWORD 的指针,然后您可以分配该缓冲区并进行第二次调用,传递分配的缓冲区。Do you control the implementation of the
archive
function? If you do then you have a few options.1- Have the
archive
function allocate the buffer and return it to the caller. The down side is that the caller wil need to use the right function to free the buffer otherwise risk either memory leak and even corrupting the heap.2- Pass the size of the buffer you have to the
archive
function so that it will not exceed the buffer length when filling the buffer.3- If you can have a function that can return the required buffer size then you can use that. This is a common approach in the windows API, passing
null
as the buffer and a pointer to a DWORD which receives the required buffer size, which you can then allocate and make a second call passing the allocated buffer.我会让非托管代码分配内存,然后让托管端通过 IntPtr 将其复制到托管数组中并释放分配。
您需要首先使非托管函数返回其输出数组的大小:
然后托管端需要将其作为 IntPtr 获取:
您没有指定数据是否实际上是字符串,或者是否使用字符串缓冲区来保存不透明二进制数据。如果响应数据是以 null 结尾的字符串,那么您可以轻松使用
PtrToStringUni
或PtrToStringAnsi
来获取string
而不是简单的数组:非托管方面:
在托管方面:
注意:我没有测试任何此代码,因此可能存在一些小遗漏或错误......
I would have the unmanaged code allocate the memory, then let the managed side copy it into a managed array via an IntPtr and release the allocation.
You need to first make your unmanaged function return the size of it's output array:
Then the managed side needs to get it as an IntPtr:
You didn't specify if your data was actually a string or if you were using a stringbuffer to hold opaque binary data. If the response data is a null-terminated string then you can easily use
PtrToStringUni
orPtrToStringAnsi
to get astring
instead of a simple array:On the unmanaged side:
On the managed side:
NB: I didn't test any of this code, so there may be some small omissions or bugs...
我曾经遇到过一个非常类似的问题,但是我有dll的源代码,所以我添加了一个可以转储文件的函数,新的调用如下所示:
然后我将只读取文件内容
I had a very similar problem once, but I had the dll's source code, so I added a function that would dump a file, the new call looked like this:
then I would just read the file contents
您不需要为响应指定大小。
You don't need to give the response a size.