c#中如何调用这样地dll,高手请进

chinadotcom 2002-03-08 03:58:55
Dll文件是通过VC6.0编写的,其中有一个函数为:
CString FunSys(int * par1, CString par2)

请问在C#中,如何是否可以调用此函数???
如果可以,在C#中如何编写此函数地原型声明???
谢谢!!!
...全文
43 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
qqchen79 2002-03-14
  • 打赏
  • 举报
回复
sorry,忘了UnlockBuffer,:) MFC我也不是很熟的说。
qqchen79 2002-03-14
  • 打赏
  • 举报
回复
就是做一个自己的DLL,调用前面说的那个DLL里的函数。
#include <TCHAR.H>

void FunSysWrap(int* p, LPTSTR pstr, LPTSTR buffer) {
CString s(pstr);
CString ret = FunSys(p, s);
LPTSTR temp = ret.LockBuffer();
_tcscpy(buffer, temp);
return;
}

然后C#里面调用FunSysWrap(ref int, string, StringBuilder)就可以了。

至于怎么用VC生成DLL,参考MSDN的例子吧,记得把.lib包含到Project的link里面就可以了。
qqchen79 2002-03-14
  • 打赏
  • 举报
回复
Ok, I finally got this damn thing work! :)
下面是整个代码,很难解释,就将就着用把:
DLL:
CString FunSys(int* p, CString str);

C#:
[StructLayout(LayoutKind.Sequential)]
public struct MyString {
public IntPtr _str;
}

[DllImport("mydll.dll", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)]
public extern static void DllFun(IntPtr pt, ref int i, string str);
//千万别问我为什么:)

调用:
int i = 0;
IntPtr mem = Marshal.AllocHGlobal(64); //申请多点内存,先。
DllFun(mem, ref i, "hello, world");
MyString mystr = (MyString)Marshal.PtrToStructure(mem, typeof(MyString));
string str = Marshal.PtrToStringAnsi(mystr._str);
Console.WriteLine(str);
Marshal.FreeHGlobal(mem);
...

真是麻烦,乖乖妹要请客的说!:)
chinadotcom 2002-03-13
  • 打赏
  • 举报
回复
不对吧!
C#中并没有CString类呀!!!
还是说 怎样在VC6.0中如何调用吧!
谢谢
superl 2002-03-13
  • 打赏
  • 举报
回复
try below code:
写在你的调用函数前

[System.Runtime.InteropServices.DllImportAttribute("filename.dll")]
public static extern CString FunSys(int * par1, CString par2);
chinadotcom 2002-03-13
  • 打赏
  • 举报
回复
qqchen79(知秋一叶):
请问如何在vc6.0中添加一层包装。
现在只提供了DLL和lib文件。
谢谢!
谢谢各位高手!
chinadotcom 2002-03-12
  • 打赏
  • 举报
回复
qqchen79(知秋一叶):
按照你提供的方法,出现如下错误信息:
An unhandled exception of type 'System.Runtime.InteropServices.MarshalDirectiveException' occurred in CallAPI2.exe

Additional information: Method's type signature is not PInvoke compatible.
--------------
谢谢。
qqchen79 2002-03-12
  • 打赏
  • 举报
回复
其实我觉得最好还是用一层包装的方法,直接使用MFC中的类终究不是好事。
但如果你执意要用CString的话,可以试试这样:

CString在C#中的定义是:
[StructLayout(LayoutKind.Sequential)]
public struct CSString {
[MarshalAs(UnmanagedType.LPTStr)]
string _str;
}
可以把函数的返回这说明成为CSString的形式:
public static extern CSString FunSys(
ref int para1,
string para2
);
也许可以。
qqchen79 2002-03-12
  • 打赏
  • 举报
回复
算了,I give up. :(
还是加一层包装吧。
chinadotcom 2002-03-11
  • 打赏
  • 举报
回复
qqchen79(知秋一叶):

那这个问题,怎么解决???
谢谢!
qqchen79 2002-03-10
  • 打赏
  • 举报
回复
了解了,对于x86 native code而言(例如C++/C程序),返回值通常放在eax/edx寄存器当中,如果是C++中的对象,那么对象将会构件在heap中,对象的指针则放在eax中。而如果返回值是指针,如LPTSTR,那么这个指针的值直接放在eax中。这时候,返回LPTSTR和CString的堆栈结构就不同了。
Cstring的情况:
eax --> CString Object(LPSTR) ---> 实际字符串
const char*/LPSTR的情况:
eax --> 实际字符串
qqchen79 2002-03-09
  • 打赏
  • 举报
回复
果然是返回值的问题,CString作为参数Marshal成string没问题,但作为返回值的时候就有问题了。我试着把返回值类型改成const char*或者LPTSTR,调用就没问题了,这和int参数无关,ref和out都是可以的。
chinadotcom 2002-03-09
  • 打赏
  • 举报
回复
各位大侠,请发话吧!
小妹在此等候多时了!!!
qqchen79 2002-03-09
  • 打赏
  • 举报
回复
看了MFC的源码,原来CString里面就只有一个LPTSTR数据成员,而且没有virtual函数,所以其内存结构与LPTSTR完全一样,直接Marshal成LPTSTR也能工作——虽然感觉上不太好。

int*,有几种办法,最简单的使用ref/out就应该可以:
string FunSys(ref int a, string b);
string FunSys(out int a, string b); //急得调用的时候也要加ref/out

其次,用unsafe code,是可以取得int*的,所以可以直接用int*声明。
最后,Marshal.HGlobalAlloc可以在GlobalHeap中申请内存,返回IntPtr,相当于int*,所以也可以这样写:
string FunSys(IntPtr pa, string b); //用完记得释放。
chinadotcom 2002-03-09
  • 打赏
  • 举报
回复
我的代码是这样写的,执行的时候总是报错。
请指教,谢谢!
------------
An unhandled exception of type 'System.NullReferenceException' occurred in CallAPI2.exe
Additional information: Object reference not set to an instance of an object.
------------
源代码:
private void button1_Click(object sender, System.EventArgs e)
{
string a="aaa";
string strResult="";
int i=0;
strResult = FunSys(ref i, a);
}
[DllImport("DllName.dll",CharSet=CharSet.Auto)]
public static extern string FunSys(
ref int para1,
string para2
);
chinadotcom 2002-03-08
  • 打赏
  • 举报
回复
=====>>> qqchen79(知秋一叶):
谢谢。
我也有这种想法。
不过,不知可不可以直接在C#进行调用?
我试了一下,好像直接在c#中使用string就可以了.
关键是: int *怎么处理。
它通过int *来传出函数的执行情况,并据此判断、处理?
谢谢!!!
qqchen79 2002-03-08
  • 打赏
  • 举报
回复
看清楚了!返回和参数可是CString啊!
我还真不知道C#怎么Marshal CString呢:),要真像这样做还得费不少功夫呢!
我的建议是:先用VC++做一层包装。这个Wrap的工作就是把CString的参数和返回值转换成标准的const char*。然后把这个Wrap也编译成Dll,从C#中直接用这个Wrap的DLL。这样要容易得多。
我不懂电脑 2002-03-08
  • 打赏
  • 举报
回复
好象只要user了库就可以直接用了。
stone_fred 2002-03-08
  • 打赏
  • 举报
回复
那要看是什么DLL,是WIN32 DLL还是COM DLL呢
具体请看C# interop的解析。是关于如何工作于
unsafe code
zjq1980 2002-03-08
  • 打赏
  • 举报
回复
DllImport

.net frameworksdk documentation -> reference -> Compiler and Language Reference -> C# -> C# programmer's Reference -> C# tutorials -> platform invoke tutorials

110,538

社区成员

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

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

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