c#调用c++ dll:担心可重入问题!

wugamp 2017-01-10 02:56:32
我要用c#调用c++ dll,惯常做法是用 DllImport 来声明,但这就要求必须是 static extern。例如:
[DllImport("DLL64.dll", EntryPoint = "GetVersion", CallingConvention = CallingConvention.Cdecl)]
public static extern int GetVersion(ref byte sOutProtocol);

问题是:我将要开6个线程,各自调用一个DLL,同时处理。因此,DLL必须是可重入的。
而这显然是 static 矛盾。因为各线程调用 DLL 时使用的是同一块内存区域,很可能第一个线程刚调用了一半,第二个线程冲进来把数据给改了。
当然以上只是猜测,我一时也想不到什么办法来验证。
请问大侠:我的担忧是否多余?如果是,如何避免呢?
谢谢!
...全文
268 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
花开花折 2017-01-11
  • 打赏
  • 举报
回复
引用 4 楼 hdt 的回复:
如果你的dll里面的函数不涉及static变量,和全局变量,不用考虑多线程问题! 因为你面的函数 只是可执行代码,不是数据,且每个线程有自己的局部存储,也就是说有各自的堆栈!
同意
真相重于对错 2017-01-11
  • 打赏
  • 举报
回复
你的第二段代码,用到了static变量,就像我前面说过的,如果那个dll不用到static,全局变量,不用考虑
真相重于对错 2017-01-11
  • 打赏
  • 举报
回复
你认为,把函数申明为static.里面的局部变量,就会有冲突,你试过吗?
真相重于对错 2017-01-11
  • 打赏
  • 举报
回复
你认为,把函数申明为static.里面的局部变量,就会有冲突,你试过吗?
Forty2 2017-01-11
  • 打赏
  • 举报
回复
static并不意味着不可重入,具体还要看C++的实现(或者函数文档等)。

class My
{
    public static string 可重入(int i)
    {
        // 函数是static,但是可以重入。
        return "双倍=" + (i+i);
    }

    public static string 不可重入(int i)
    {
        si = i;
        // 如果这时其他线程条调用该函数,si就会被覆盖,结果就是错误的。
        return "双倍=" + (si + i);
    }
    static int si;
}
wugamp 2017-01-11
  • 打赏
  • 举报
回复
引用 4 楼 hdt 的回复:
如果你的dll里面的函数不涉及static变量,和全局变量,不用考虑多线程问题! 因为你面的函数 只是可执行代码,不是数据,且每个线程有自己的局部存储,也就是说有各自的堆栈!
在 C# 里,为了用 DllImport 导入 DLL的函数,必须把这个函数声明成 static 的。
wugamp 2017-01-11
  • 打赏
  • 举报
回复
引用 8 楼 hdt 的回复:
你认为,把函数申明为static.里面的局部变量,就会有冲突,你试过吗?
多谢指点。刚才试验了一下,没有冲突。代码如下: DLL部分: int iii(unsigned char a, int j, unsigned char *s2000A) { for (int idx =0; idx < 2000; idx++) s2000A[idx] = a; return j+1; } C#部分: private void th(object o) { string s = (string)o; while (true) { RNGCryptoServiceProvider csp = new RNGCryptoServiceProvider(); int i = csp.GetHashCode(); byte[] s2000B = new byte[2000]; byte a = 65; int k = CLASS_IXDC.iii(a, i, ref s2000B[0]); if (k != i + 1) MessageBox.Show("no!!!!" + s); } } 然后同时开了 24 个 th线程,运行了几个小时都没对话框出来。
threenewbee 2017-01-10
  • 打赏
  • 举报
回复
用lock同步下,避免重入
真相重于对错 2017-01-10
  • 打赏
  • 举报
回复
如果你的dll里面的函数不涉及static变量,和全局变量,不用考虑多线程问题! 因为你面的函数 只是可执行代码,不是数据,且每个线程有自己的局部存储,也就是说有各自的堆栈!
wugamp 2017-01-10
  • 打赏
  • 举报
回复
引用 2 楼 Libby1984 的回复:
既然是c#调用函数,那你就在调用函数的C#代码上加锁呗。 定义一个全局的object lockObj lock(lockObj) { // 调用C++函数 } 当然,要保证所有的调用代码都是这么调用的,最好你写成一个函数共用。
二位说的办法我也想到过,还是觉得麻烦。几个线程之间通过消息、事件互相通信,一不当心就完蛋。而且,一个DLL线程为6个通讯线程服务,也容易导致通信延迟。 有没有更好的办法?
  • 打赏
  • 举报
回复
既然是c#调用函数,那你就在调用函数的C#代码上加锁呗。 定义一个全局的object lockObj lock(lockObj) { // 调用C++函数 } 当然,要保证所有的调用代码都是这么调用的,最好你写成一个函数共用。
吉普赛的歌 2017-01-10
  • 打赏
  • 举报
回复
在C#调用c++dll之前加锁, 用完再解锁。

110,567

社区成员

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

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

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