我已在 C# 程序中声明了一个 DLL 导入,如下所示:
[DllImport("C:\\c_keycode.dll", EntryPoint = "generateKeyCode",
CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr generateKeyCode(char[] serial, char[] option, char c_type);
它引用了 DLL 内部的函数 generateKeyCode()
。
下面是导致错误的代码(使用断点):
const char* generateKeyCode(char serial[],
char option[],
char c_type)
{
returnBufferString = "";
SHA1_CTX context;
int optionLength = 0;
#ifdef WIN32
unsigned char buffer[16384] = {0};
#else
unsigned char buffer[256] = {0};
#endif
//char output[80];
char keycode[OPTION_KEY_LENGTH+1] = "";
int digest_array_size = 10; //default value for digest array size
unsigned char digest[20] = {0};
char optx[24] = {0};
char c_type_upper;
// Combine serial # and Option or Version number
char str1[30] = {0};
int i;
int size = 0;
int pos = 0;
...
...
}
基本上,我导入了这个 DLL,这样我就可以传递函数参数,它可以执行其算法并简单地返回结果。我使用了这个封送拆收器功能...
public static string genKeyCode_marshal(string serial, string option, char type)
{
return Marshal.PtrToStringAnsi(generateKeyCode(serial.ToCharArray(),
option.ToCharArray(), type));
}
...所以我可以正确进行调用。在我的 C++ 头文件内部,我定义了一个字符串,如所示,这对于回答此问题很有帮助 问题(它是 C/C++ 函数顶部的 returnBufferString
变量)。
当我使用 NumericUpDown
控件以 0.1 的增量从 1.0 到 9.9(每次向上或向下伴随另一个函数调用)时,我多次调用此函数,然后再次向下。然而,每次我尝试这样做时,程序都会在看似设定数量的函数调用后卡住(如果我只是直接上下移动,则在返回的途中停止在 1.9 处,或者如果我稍微上下交替,则在返回时停止在 1.9 处) 。
请注意,它有效并为我提供了我想要的值,没有任何差异。
我将缓冲区大小更改为较小的数字(5012),当我尝试运行该程序时,在第一个函数调用时它抛出了 AccessViolationException。然而,将缓冲区大小加倍到原始缓冲区大小的两倍 (32768) 与原始缓冲区大小相比没有任何效果 - 从 1.0 直接上升到 9.9,然后再次下降,它在 1.9 处停止并抛出异常。
编辑:默认是 ANSI,所以它是 ANSI。那里没有问题。这是内存分配问题吗?
I have declared a DLL import in my C# program that looks like this:
[DllImport("C:\\c_keycode.dll", EntryPoint = "generateKeyCode",
CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr generateKeyCode(char[] serial, char[] option, char c_type);
It references the function generateKeyCode()
inside of my DLL.
Here is the code that is causing an error (used breakpoints):
const char* generateKeyCode(char serial[],
char option[],
char c_type)
{
returnBufferString = "";
SHA1_CTX context;
int optionLength = 0;
#ifdef WIN32
unsigned char buffer[16384] = {0};
#else
unsigned char buffer[256] = {0};
#endif
//char output[80];
char keycode[OPTION_KEY_LENGTH+1] = "";
int digest_array_size = 10; //default value for digest array size
unsigned char digest[20] = {0};
char optx[24] = {0};
char c_type_upper;
// Combine serial # and Option or Version number
char str1[30] = {0};
int i;
int size = 0;
int pos = 0;
...
...
}
Basically, I imported this DLL so I could pass the function parameters and it could do its algorithm and simply return me a result. I used this marshaler function...
public static string genKeyCode_marshal(string serial, string option, char type)
{
return Marshal.PtrToStringAnsi(generateKeyCode(serial.ToCharArray(),
option.ToCharArray(), type));
}
...so I could make the call properly. Inside of my C++ header file, I have defined a string, as indicated is helpful in the answer to this question (it is the returnBufferString
variable present at the top of the C/C++ function).
I make this function call several times as I use a NumericUpDown
control to go from 1.0 to 9.9 in increments of 0.1 (each up or down accompanies another function call), and then back down again. However, every time I try to do this, the program hitches after a seemingly set number of function calls (stops at 1.9 on the way back down if I just go straight up and down, or earlier if I alternate up and down a bit).
Please note that it works and gives me the value I want, there are no discrepancies there.
I changed the buffer size to some smaller number (5012) and when I tried to run the program, on the first function call it threw the AccessViolationException. However, doubling the buffer size to twice (32768) the original had no effect in comparison to the original -- going straight up to 9.9 from 1.0 and down back again, it stops at 1.9 and throws the exception.
EDIT: Default is ANSI, so it is ANSI. No problems there. Is this a memory allocation issue??
发布评论
评论(2)
我建议尝试以下操作:
注意
DllImport
属性的新CharSet
字段。下一个想法是显式使用
MarshalAs
属性:I would suggest trying the following:
Note the new
CharSet
field ofDllImport
attribute.Next idea is to use
MarshalAs
attribute explicitely:我知道这可能不能令人满意,但是一旦我删除了用于从 C/C++ DLL 中调试的输出重定向,问题就停止了。现在一切正常,所以我想这基本上等同于回答我自己的问题。感谢大家的回复。
I know this may be unsatisfactory, but once I removed the output redirection I was using to debug from within my C/C++ DLL, the problem stopped. Everything works now, so I guess that's essentially equivalent to answering my own question. Thanks to everyone for the replies.