int Test(LP_TEST_CALL_BACK_FUNC callback)
{
m_gCallBackFun = callback;//保存回调函数指针值
}
要求传入的参数是一个回调函数指针。回调函数的原型要求为:
void testCallBack(BYTE *pData,int nLen)
{
//对pData数据进行处理。
}
//dll里面的函数调用回调函数处理
void dellData()
{
byte data[100];
for(byte i = 0 ;i < 100;i++)
data[i] = i;
//调用C#传入的回调函数处理这些值
m_gCallBackFun(data,100); //问题在此,调用完后出错,此时C#里的回调函数代码已经执行完。
}
上层模块是用C#写的,现在用C#调用testCallBack接口
C#里
[DllImport("Test.dll")]
public static extern void testCallBack(BYTE []data,int nlen);
void Test()
{
testCallBack(testCallBack);
}
void testCallBack(BYTE *pData,int nLen)
{
//对pData数据进行处理。
//......
MessageBox.show("数据执行完毕"); //dll调用回调函数处理时 本对话框已经弹出,数据已经处理完毕!
}
现在的问题是,每次dll里面执行这个回调函数指针,程序都会报错,说什么访问了非法的内存。请问有没有朋友遇到过这种问题?现在焦头烂额,请大家帮忙看看问题出在哪儿?
13 个解决方案
#1
不好意思,下面一部分写错了,是这样
程序中有个模块是用C++写的,封装成了 dll文件,接口名称如下:
int RegCallBack(LP_TEST_CALL_BACK_FUNC callback)
{
m_gCallBackFun = callback;//保存回调函数指针值
}
要求传入的参数是一个回调函数指针。回调函数的原型要求为:
void testCallBack(BYTE *pData,int nLen)
{
//对pData数据进行处理。
}
//dll里面的函数调用回调函数处理
void dellData()
{
byte data[100];
for(byte i = 0 ;i < 100;i++)
data[i] = i;
//调用C#传入的回调函数处理这些值
m_gCallBackFun(data,100); //问题在此,调用完后出错,此时C#里的回调函数代码已经执行完。
}
上层模块是用C#写的,现在用C#调用testCallBack接口
C#里
[DllImport("Test.dll")]
public static extern void RegCallBack(BYTE []data,int nlen);
void Test()
{
RegCallBack(testCallBack);
}
void testCallBack(BYTE *pData,int nLen)
{
//对pData数据进行处理。
//......
MessageBox.show("数据执行完毕"); //dll调用回调函数处理时 本对话框已经弹出,数据已经处理完毕!
}
现在的问题是,每次dll里面执行这个回调函数指针,程序都会报错,说什么访问了非法的内存。请问有没有朋友遇到过这种问题?现在焦头烂额,请大家帮忙看看问题出在哪儿?
程序中有个模块是用C++写的,封装成了 dll文件,接口名称如下:
int RegCallBack(LP_TEST_CALL_BACK_FUNC callback)
{
m_gCallBackFun = callback;//保存回调函数指针值
}
要求传入的参数是一个回调函数指针。回调函数的原型要求为:
void testCallBack(BYTE *pData,int nLen)
{
//对pData数据进行处理。
}
//dll里面的函数调用回调函数处理
void dellData()
{
byte data[100];
for(byte i = 0 ;i < 100;i++)
data[i] = i;
//调用C#传入的回调函数处理这些值
m_gCallBackFun(data,100); //问题在此,调用完后出错,此时C#里的回调函数代码已经执行完。
}
上层模块是用C#写的,现在用C#调用testCallBack接口
C#里
[DllImport("Test.dll")]
public static extern void RegCallBack(BYTE []data,int nlen);
void Test()
{
RegCallBack(testCallBack);
}
void testCallBack(BYTE *pData,int nLen)
{
//对pData数据进行处理。
//......
MessageBox.show("数据执行完毕"); //dll调用回调函数处理时 本对话框已经弹出,数据已经处理完毕!
}
现在的问题是,每次dll里面执行这个回调函数指针,程序都会报错,说什么访问了非法的内存。请问有没有朋友遇到过这种问题?现在焦头烂额,请大家帮忙看看问题出在哪儿?
#2
BYTE *pData这个改成 byte[]看看 要不你去找找c++和c#类型定义表
#3
byte[]也不行,我试过了。暂时没想到好的方法,有一个workaround
就是buffer也是从C#传过去的,然后在dellData中对这个传入的buffer进行操作。
我的测试代码
C++端声明:
实现:
C#端:
就是buffer也是从C#传过去的,然后在dellData中对这个传入的buffer进行操作。
我的测试代码
C++端声明:
typedef int (*LP_TEST_CALL_BACK_FUNC)(char* pData, int nLen);
extern "C" HASP_EXT_API void Test();
extern "C" HASP_EXT_API void SetCallBack(LP_TEST_CALL_BACK_FUNC fp, char* pBuffer, int len);
实现:
LP_TEST_CALL_BACK_FUNC g_fp = NULL;
char* g_pBuffer = NULL;
int g_len = 0;
extern "C" void Test()
{
if (g_fp != NULL)
{
for(char i = 0 ;i < g_len -1;i++)
g_pBuffer[i] = i;
//g_fp(data,len);
}
}
extern "C" void SetCallBack(LP_TEST_CALL_BACK_FUNC fp, char* pBuffer, int len)
{
g_fp = fp;
g_pBuffer = pBuffer;
g_len = len;
}
C#端:
unsafe public delegate int Mydelegate(byte* data, int nLen);
unsafe private int test(byte* data, int nLen)
{
return 1;
}
unsafe private void button1_Click(object sender, EventArgs e)
{
byte[] buffer = new byte[100];
for (int i = 0; i<100; ++i)
{
buffer[i] = 0;
}
Mydelegate pf = new Mydelegate(test);
SetCallBack(pf, buffer, 100);
Test();
}
[DllImport("TestPVCallback.dll")]
public static extern void SetCallBack(Mydelegate fp, byte[] data, int nLen);
[DllImport("TestPVCallback.dll")]
public static extern void Test();
#4
Good luck!
#5
有没有高手帮帮忙啊? 因为我们有很多个dll模块都是要求传入这样一样类似的函数指针,由模块与其他程序和各种设备进行通讯,然后传给上层的C#程序.以前我用C++写程序就不会有这个问题,怎么换成了C#就这么麻烦.着急呀,老大.
#6
unsafe private int test(byte* data, int nLen)
加个static试一试
加个static试一试
#8
用委托试下?
#9
难道每一个高手弄过吗?痛苦哦。
我用得unsafe语句,没用,跟这个无关。
我用得unsafe语句,没用,跟这个无关。
#10
C++的函数指针在C#的DllImport里要声明成委托
#11
希望有高手能自己写段简单的代码自己测试一下! 3楼的朋友很感谢你,就是那样的写法,但问题没解决呀!
#12
还没解决。关注,帮顶。
lz,实在不行我还有一个workaround.
就是在C++端编码,变成可视字符,然后在C#端解码。
例如使用Base64编码成字符串,再在C#端解码变成byte[]
lz,实在不行我还有一个workaround.
就是在C++端编码,变成可视字符,然后在C#端解码。
例如使用Base64编码成字符串,再在C#端解码变成byte[]
#13
把指针换成IntPtr,不能使用byte【】这种形式,我上次也出现过这种问题的,网上很多说要用数组的形式,其实是不对的,要用IntPtr类型,在到C#这边就行转换就可以了。。
#1
不好意思,下面一部分写错了,是这样
程序中有个模块是用C++写的,封装成了 dll文件,接口名称如下:
int RegCallBack(LP_TEST_CALL_BACK_FUNC callback)
{
m_gCallBackFun = callback;//保存回调函数指针值
}
要求传入的参数是一个回调函数指针。回调函数的原型要求为:
void testCallBack(BYTE *pData,int nLen)
{
//对pData数据进行处理。
}
//dll里面的函数调用回调函数处理
void dellData()
{
byte data[100];
for(byte i = 0 ;i < 100;i++)
data[i] = i;
//调用C#传入的回调函数处理这些值
m_gCallBackFun(data,100); //问题在此,调用完后出错,此时C#里的回调函数代码已经执行完。
}
上层模块是用C#写的,现在用C#调用testCallBack接口
C#里
[DllImport("Test.dll")]
public static extern void RegCallBack(BYTE []data,int nlen);
void Test()
{
RegCallBack(testCallBack);
}
void testCallBack(BYTE *pData,int nLen)
{
//对pData数据进行处理。
//......
MessageBox.show("数据执行完毕"); //dll调用回调函数处理时 本对话框已经弹出,数据已经处理完毕!
}
现在的问题是,每次dll里面执行这个回调函数指针,程序都会报错,说什么访问了非法的内存。请问有没有朋友遇到过这种问题?现在焦头烂额,请大家帮忙看看问题出在哪儿?
程序中有个模块是用C++写的,封装成了 dll文件,接口名称如下:
int RegCallBack(LP_TEST_CALL_BACK_FUNC callback)
{
m_gCallBackFun = callback;//保存回调函数指针值
}
要求传入的参数是一个回调函数指针。回调函数的原型要求为:
void testCallBack(BYTE *pData,int nLen)
{
//对pData数据进行处理。
}
//dll里面的函数调用回调函数处理
void dellData()
{
byte data[100];
for(byte i = 0 ;i < 100;i++)
data[i] = i;
//调用C#传入的回调函数处理这些值
m_gCallBackFun(data,100); //问题在此,调用完后出错,此时C#里的回调函数代码已经执行完。
}
上层模块是用C#写的,现在用C#调用testCallBack接口
C#里
[DllImport("Test.dll")]
public static extern void RegCallBack(BYTE []data,int nlen);
void Test()
{
RegCallBack(testCallBack);
}
void testCallBack(BYTE *pData,int nLen)
{
//对pData数据进行处理。
//......
MessageBox.show("数据执行完毕"); //dll调用回调函数处理时 本对话框已经弹出,数据已经处理完毕!
}
现在的问题是,每次dll里面执行这个回调函数指针,程序都会报错,说什么访问了非法的内存。请问有没有朋友遇到过这种问题?现在焦头烂额,请大家帮忙看看问题出在哪儿?
#2
BYTE *pData这个改成 byte[]看看 要不你去找找c++和c#类型定义表
#3
byte[]也不行,我试过了。暂时没想到好的方法,有一个workaround
就是buffer也是从C#传过去的,然后在dellData中对这个传入的buffer进行操作。
我的测试代码
C++端声明:
实现:
C#端:
就是buffer也是从C#传过去的,然后在dellData中对这个传入的buffer进行操作。
我的测试代码
C++端声明:
typedef int (*LP_TEST_CALL_BACK_FUNC)(char* pData, int nLen);
extern "C" HASP_EXT_API void Test();
extern "C" HASP_EXT_API void SetCallBack(LP_TEST_CALL_BACK_FUNC fp, char* pBuffer, int len);
实现:
LP_TEST_CALL_BACK_FUNC g_fp = NULL;
char* g_pBuffer = NULL;
int g_len = 0;
extern "C" void Test()
{
if (g_fp != NULL)
{
for(char i = 0 ;i < g_len -1;i++)
g_pBuffer[i] = i;
//g_fp(data,len);
}
}
extern "C" void SetCallBack(LP_TEST_CALL_BACK_FUNC fp, char* pBuffer, int len)
{
g_fp = fp;
g_pBuffer = pBuffer;
g_len = len;
}
C#端:
unsafe public delegate int Mydelegate(byte* data, int nLen);
unsafe private int test(byte* data, int nLen)
{
return 1;
}
unsafe private void button1_Click(object sender, EventArgs e)
{
byte[] buffer = new byte[100];
for (int i = 0; i<100; ++i)
{
buffer[i] = 0;
}
Mydelegate pf = new Mydelegate(test);
SetCallBack(pf, buffer, 100);
Test();
}
[DllImport("TestPVCallback.dll")]
public static extern void SetCallBack(Mydelegate fp, byte[] data, int nLen);
[DllImport("TestPVCallback.dll")]
public static extern void Test();
#4
Good luck!
#5
有没有高手帮帮忙啊? 因为我们有很多个dll模块都是要求传入这样一样类似的函数指针,由模块与其他程序和各种设备进行通讯,然后传给上层的C#程序.以前我用C++写程序就不会有这个问题,怎么换成了C#就这么麻烦.着急呀,老大.
#6
unsafe private int test(byte* data, int nLen)
加个static试一试
加个static试一试
#7
#8
用委托试下?
#9
难道每一个高手弄过吗?痛苦哦。
我用得unsafe语句,没用,跟这个无关。
我用得unsafe语句,没用,跟这个无关。
#10
C++的函数指针在C#的DllImport里要声明成委托
#11
希望有高手能自己写段简单的代码自己测试一下! 3楼的朋友很感谢你,就是那样的写法,但问题没解决呀!
#12
还没解决。关注,帮顶。
lz,实在不行我还有一个workaround.
就是在C++端编码,变成可视字符,然后在C#端解码。
例如使用Base64编码成字符串,再在C#端解码变成byte[]
lz,实在不行我还有一个workaround.
就是在C++端编码,变成可视字符,然后在C#端解码。
例如使用Base64编码成字符串,再在C#端解码变成byte[]
#13
把指针换成IntPtr,不能使用byte【】这种形式,我上次也出现过这种问题的,网上很多说要用数组的形式,其实是不对的,要用IntPtr类型,在到C#这边就行转换就可以了。。