请教 :C# 调用 DLL(C++) 的问题 (关于返回 char[]) 。 谢谢先 [刚才搜索了一下,没有找到答案]

双子东宝 2005-08-23 05:23:07
DLL 中函数定义如下
/*++------------------------------------------------------------------------
Function:
EncryptDES
Parameters:
[out] e_bit Encryption data
[in] k_bit Key data
[in] m_bit Uncryption data
--------------------------------------------------------------------------*/
extern "C"
_declspec(dllexport)
void
__stdcall
EncryptDES(unsigned char m_bit[8] ,
unsigned char k_bit[8] ,
unsigned char e_bit[8]);

----------------------------------------------------------------------------------

在C#中定义如下:
[DllImport("NetEagle.dll",EntryPoint="EncryptDES")]
public static extern void EncryptDES( ref StringBuilder m_bit ,
StringBuilder k_bit ,
StringBuilder e_bit);

----------------------------------------------------------------------------------

调用如下:
private void button1_Click(object sender, System.EventArgs e)
{
StringBuilder strE = new StringBuilder("12345678");
StringBuilder strK = new StringBuilder("kill");
StringBuilder strM = new StringBuilder(8);

TransferDll execTransferDll = new TransferDll();
execTransferDll.EncryptDES(ref strM,strK,strE);
}

调用后 返回值(m_bit)为空。
请问是什么原因?如何解决?
谢谢

...全文
366 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
双子东宝 2005-08-24
  • 打赏
  • 举报
回复
谢谢Sunmast(速马/MVP)

问题解决了,
对于返回值是 char[] , 不用 ref 就可以传回 ,用了ref 却报错 “未将对象引用设置到对象的实例”



再次感谢 Sunmast(速马/MVP) 的耐心解答。


另: csdn 的结帖规矩咋那么多?
竟然不让结帖, 说什么
"85,0,0,0,5,0,5,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0
贴子回复次数大于跟给分次数 "
投诉去
速马 2005-08-24
  • 打赏
  • 举报
回复
>>> extern "C" __declspec(dllexport) int StringInputOutput(char p1[8], char p2[8]
速马 2005-08-24
  • 打赏
  • 举报
回复
test:

extern "C" __declspec int StringInputOutput(char p1[8], char p2[8])
{
cout << p1 << endl;
memcpy(p2, "test", 5);
return 42;
}

[DllImport(dllPath)]
public static extern int StringInputOutput(string p1, StringBuilder p2);

[STAThread]
static void Main(string[] args)
{
StringBuilder p2 = new StringBuilder();
StringInputOutput("test", p2);
Console.WriteLine(p2.ToString());
Console.ReadLine();
}
速马 2005-08-24
  • 打赏
  • 举报
回复
sorry, 我从来不会给函数传char xxx[n]这样的参数,都是char* ...
是我弄错了嗯,char[8]传送的也是指针,这样的话:

extern "C"
_declspec(dllexport)
void
__stdcall
EncryptDES(unsigned char m_bit[8] ,
unsigned char k_bit[8] ,
unsigned char e_bit[8]);

[DllImport("NetEagle.dll",EntryPoint="EncryptDES")]
public static extern void EncryptDES( StringBuilder m_bit ,
string k_bit ,
string e_bit);
速马 2005-08-24
  • 打赏
  • 举报
回复
不能用ref string或者ref StringBuilder,语义都不对

vc++中
void getcharpoint( char * chName ){ memcpy(chName,"mytest",8); }

c#中
[DllImport("chartest.dll",EntryPoint="getcharpoint")]
private static extern void getcharpoint(StringBuilder chName );

StringBuilder chName = new StringBuilder();
getcharpoint(chName);
string result = chName.ToString();

>>> 如果我在我加的那层外壳上使用ref的话,编译通过,当时调用依然报错,错误同以前一样
当然要出错,因为你传递了一个指针,实际需要的是char[8]
速马 2005-08-24
  • 打赏
  • 举报
回复
>>> 在vc 中, char[] 在传递时应该是char[0]的指针
用char[8]则是传递数组的整个拷贝,不是首元素指针
双子东宝 2005-08-24
  • 打赏
  • 举报
回复
刚才试了一下 ,
[DllImport("NetEagle.dll",EntryPoint="EncryptDES")]
private static extern void EncryptDES( Char8 m_bit , Char8 k_bit , Char8 e_bit );

EncryptDES( ref m_bit,k_bit,e_bit);
这样编译会抱错,
F:\SingleApp\PlatformTest\CPoint\TransferDll.cs(51): 参数“1” : 无法从“ref PlatformTest.Char8”转换为“PlatformTest.Char8”

如果我在我加的那层外壳上使用ref的话,编译通过,当时调用依然报错,错误同以前一样。



-------------------------------------------------------------------------------------
另外,我自己用vc写了一个dll,然后在c#中调用,同样报 “未将对象引用设置到对象的实例”的错误。代码如下
vc++中
void getcharpoint( char * chName ){ memcpy(chName,"mytest",8); }

c#中
[DllImport("chartest.dll",EntryPoint="getcharpoint")]
private static extern void getcharpoint(ref StringBuilder chName );

public void dllgetcharpoint(ref StringBuilder chName )
{
getcharpoint(ref chName );
}

速马 2005-08-24
  • 打赏
  • 举报
回复
还有你的注释和代码都没有匹配嗯
双子东宝 2005-08-24
  • 打赏
  • 举报
回复
这个DLL 是用vc++写的, 使用vc++ 调用是没有问题的。
在vc 中, char[] 在传递时应该是char[0]的指针。
速马 2005-08-24
  • 打赏
  • 举报
回复
[DllImport("NetEagle.dll",EntryPoint="EncryptDES")]
private static extern void EncryptDES( Char8 m_bit , Char8 k_bit , Char8 e_bit );

EncryptDES( ref m_bit,k_bit,e_bit);

能编译通过吗?用ref就是传指针,你要的是char[8],还是不对
要传出数据就应该用char*,你用的是char[8],C++那头都不对
速马 2005-08-24
  • 打赏
  • 举报
回复
嗯,这里确实有问题,既然是传出参数,那怎么可以声明为char[8],必须使用char*

楼上的不对
双子东宝 2005-08-24
  • 打赏
  • 举报
回复
首先感谢Sunmast(速马/MVP)的耐心解答 及各位朋友的帮助。

现在的问题:
未处理的“System.NullReferenceException”类型的异常出现在 PlatformTest.exe 中。
其他信息: 未将对象引用设置到对象的实例。

在定义完结构后,
定义dll 如下:
[DllImport("NetEagle.dll",EntryPoint="EncryptDES")]
private static extern void EncryptDES( Char8 m_bit , Char8 k_bit , Char8 e_bit );

public void dllEncryptDES( Char8 m_bit , Char8 k_bit , Char8 e_bit)
{
EncryptDES( ref m_bit,k_bit,e_bit);
}

调用如下:
Char8 chM,chK,chE ;
chM.Value = "00000000";
chK.Value = "kile";
chE.Value="12345678";

execTransferDll.dllEncryptDES( chM,chK,chE);
提示错误如上所示:
zhouxm2003 2005-08-24
  • 打赏
  • 举报
回复
传出字符串要用双重指针char** ..在C#用ref string 标明
速马 2005-08-24
  • 打赏
  • 举报
回复
sorry, 上面给的代码未经测试
try again:
public struct Char8
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=8)]
public string Value;
}

[DllImport("NetEagle.dll",EntryPoint="EncryptDES")]
public static extern void EncryptDES(Char8 m_bit, ...
zhouxm2003 2005-08-24
  • 打赏
  • 举报
回复
传出字符串要用又重指针..在C#用ref string 标明
双子东宝 2005-08-24
  • 打赏
  • 举报
回复
编译错误:
发出“System.Runtime.InteropServices.MarshalAsAttribute”属性时出错 -- “指定的非托管类型只对字段有效。”


俺对 System.Runtime.InteropServices.MarshalAsAttribute 第一次了解,不知道该如何使用。
麻烦高手给指点一下。
双子东宝 2005-08-24
  • 打赏
  • 举报
回复
TO:curlfw 
使用你的方法的返回值依然为空
curlfw 2005-08-24
  • 打赏
  • 举报
回复
用stringbuilder是没有问题的
curlfw 2005-08-24
  • 打赏
  • 举报
回复
应该是你第二个stringbuilder大小不对
marshall时数据便宜出错
也用8个大小再试试看吧
双子东宝 2005-08-24
  • 打赏
  • 举报
回复
编译错误:
发出“System.Runtime.InteropServices.MarshalAsAttribute”属性时出错 -- “指定的非托管类型只对字段有效。”


俺对 System.Runtime.InteropServices.MarshalAsAttribute 第一次了解,不知道该如何使用。
麻烦高手给指点一下。
加载更多回复(5)

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧