首先是C++的一个DLL文件
主要内容是:extern "C" __declspec(dllexport) char* getData();char DATA[1000];
double tmp;char* getData()
{
tmp= 0.55;
sprintf(DATA, "%f", tmp);
return DATA;
}
C#来调用这个DLL
c#代码是:using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;namespace WindowsApplication3
{
public partial class Form1 : Form
{ [DllImport("WaferConePreSizing.dll")]
public static extern string getData(); public Form1()
{
InitializeComponent(); string revStr = ""; revStr = getData();
}
}
}如果值是0.55就会报不能修改保护内存的错误,如果是0.45或者0.60就不会出问题
其他的值好像也都不会出问题。。
就这个 0.55期待高手解答。
谢谢~~~
主要内容是:extern "C" __declspec(dllexport) char* getData();char DATA[1000];
double tmp;char* getData()
{
tmp= 0.55;
sprintf(DATA, "%f", tmp);
return DATA;
}
C#来调用这个DLL
c#代码是:using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;namespace WindowsApplication3
{
public partial class Form1 : Form
{ [DllImport("WaferConePreSizing.dll")]
public static extern string getData(); public Form1()
{
InitializeComponent(); string revStr = ""; revStr = getData();
}
}
}如果值是0.55就会报不能修改保护内存的错误,如果是0.45或者0.60就不会出问题
其他的值好像也都不会出问题。。
就这个 0.55期待高手解答。
谢谢~~~
解决方案 »
- 解释一下代码,不懂,尤其这个PropertyChanged(this, new PropertyChangedEventArgs(property));
- 高分求解不同网段的socket通信问题
- 如何做QQ登录的提示 俅救錒 。要做项目
- 删除数据库中的重复记录,进销存中的问题
- 当new了一个class,我们的内存发生了哪些变化?
- 关于客户端用JS建立Table后的样式问题?急等高手回复
- 有什么办法 不注册前台脚本 ,打开新窗口,并获得返回值呢?
- Winform中子窗体如何添加父窗体的contextMenu菜单;以及动态修改父窗体的菜单名称,所激活的事件,等
- 关于颜色设置问题
- 用了几天c#,有些感想"C#中是区分大小写,老是要注意大小写,有些烦.不知C#是否可以和vb一样.
- c#调用c++写的dll
- 请教一个关于在C#中引用外部C API函数的问题
public static extern StringBuilder getData();
The native memory was allocated with CoTaskMemAlloc
Therefore it will marshal the string and then call CoTaskMemFree on the native memory blob. Unless you actually allocated this memory with CoTaskMemAlloc this will at best cause a crash in your application. In order to get the correct semantics here you must return an IntPtr directly. Then use Marshal.PtrToString* in order to get to a managed String value. You may still need to free the native memory but that will dependent upon the implementation of foo.
extern "C" __declspec(dllexport) char *foo(void);IntPtr ptr = foo();
string str = Marshal.PtrToStringAuto(ptr);
参考:
http://stackoverflow.com/questions/370079/pinvoke-for-c-function-that-returns-char
tmp= 0.55;
sprintf(DATA, "%f", tmp);
return DATA;s试试先转换成float.
sprintf(DATA, "%f", (float)tmp);
public static extern IntPtr getData(); public Form1()
{
InitializeComponent(); IntPtr ptr = getData(); string str = Marshal.PtrToStringAuto(ptr);
}
不行的话,再试一试:
[DllImport(_dllLocation)]
[return : MarshalAs(UnmanagedType.LPStr)]
public static extern string getData();
看来是转换完之后的字符数组作为返回值返回的时候出的问题。
因为我用c++调用这个DLL是没有问题的。
public static extern IntPtr getData(); public Form1()
{
InitializeComponent(); IntPtr ptr = getData(); string str = Marshal.PtrToStringAuto(ptr);
} 这个方法运行通过了,但是返回值是乱码,不是应该返回的那个
[System.Runtime.InteropServices.DllImportAttribute("WaferConePreSizing.dll", EntryPoint="getData")]
public static extern System.IntPtr getData() ;
IntPtr的防范修改一下试一试[DllImport("WaferConePreSizing.dll")]
public static extern IntPtr getData(); public Form1()
{
InitializeComponent(); IntPtr ptr = getData(); string tmp = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(ptr);
} 参考:
http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/df6ba613-43e7-4194-a687-15120e92ecf7/
会不会是C#和C++在内存的使用上 有不同的地方导致的。
其次.net下你用string 封送 ,框架会把值赋给revStr以后 ,会试图释放这个指针,结果出现了意想不到的情况。
做好的做法是传入char* 引用,或者
在c++dll里
tmp= 0.55;
sprintf(DATA, "%f", tmp);
return _strdup(DATA);
很有道理试了一下,果然也是可以的。
那问题就出在了,赋值以后c#进行指针释放上了?上面说的最好的做法是传入char*引用。。是不是用StringBuilder作为输出参数传过去这种做法?如果是指针释放的话,为什么其他的数是没有问题的,只是0.55才会出现问题呢?
该书的官方网站:
www.interop123.com 豆瓣网信息:
http://www.douban.com/subject/3671497/