记一次“应用程序之间的通信”过程(1/2)

最近因为项目需要在多个应用程序间互相通信。研究了几种不同的解决办法,最终实现,现记录下来以备忘。

方案一的设计思路如下:

期间碰到的问题如下:

一.  在写C++.DLL的库时, 要注意

// define function pointer

typedef void (__stdcall *React)(int msg);

// set pointer

void __stdcall SetReact(React rt)也要__stdcall

说明:也就是说如果参数是包含标准调用的函数指针,那么这个函数的定义也要是标准调用。

二. 在托管代码处。

  [UnmanagedFunctionPointer(CallingConvention.StdCall)]

        public delegate void React(int msg);

        [DllImport(@"D:\workbench\TestDelegate.dll", CallingConvention = CallingConvention.StdCall)]

        public static extern void SetReact(

            [MarshalAs(UnmanagedType.FunctionPtr)]

            React rt

        );

说明:委托要指明UnmanagedFunctionPointer和StdCall 。 其次,MarshalAs(UnmanagedType.FunctionPtr)这里也要注意MarshaAs和标准调用。

三. 当上面的环节没有问题了, 开始调用后始终报异常。“函数指针 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”

最终发现: 共享dll内存数据不能共享函数指针。 过程摘录如下:

  1. // Global and static member variables that are not shared.
    ...

    #pragmadata_seg("SHARED"// Begin the shared data segment.
    // Define simple variables
    // Integers, char[] arrays and pointers
    // Do not define classes that require 'deep' copy constructors.
    #pragmadata_seg()          // End the shared data segment and default back to
                                // the normal data segment behavior.

    // This is the most important statement of all
    // Ideally you can set this in the projects linker tab, but I never could get
    // that to work.  I stumbled across this in a discussion board response from
    // Todd Jeffreys.  This tells the linker to generate the
    shared data segment. 
    // It does not tell it what variables are
    shared, the other statements do that,
    // but it does direct the linker to make provisions for the
    shared data segment.
    #pragma comment(linker, "/section:SHARED,RWS")

 

源文档 <http://www.codeproject.com/Articles/240/How-to-share-a-data-segment-in-a-DLL>

 

  1.  

1#pragma data_seg()一般用于DLL中。也就是说,在DLL中定义一个共享的,有名字的数据段。最关键的是:

    这个数据段中的全局变量可以被多个进程共享。否则多个进程之间无法共享DLL中的全局变量。

2,共享数据必须初始化,否则微软编译器会把没有初始化的数据放到.BSS段中,从而导致多个进程之间的共

    享行为失败。

3,你所谓的结果正确是一种错觉。如果你在一个DLL中这么写:

 

    #pragma data_seg("MyData")

 

    int g_Value; // Note that the global is not initialized.

 

    #pragma data_seg()

 

    DLL提供两个接口函数:

 

    int GetValue()

    {

        return g_Value;

    }

 

    void SetValue(int n)

    {

        g_Value = n;

    }

 

然后启动两个进程A和B,A和B都调用了这个DLL,假如A调用了SetValue(5); B接着调用int m = GetValue(); 

那么m的值不一定是5,而是一个未定义的值。因为DLL中的全局数据对于每一个调用它的进程而言,是私有的,

不能共享的。假如你对g_Value进行了初始化,那么g_Value就一定会被放进MyData段中。换句话说,如果A调用

了SetValue(5); B接着调用int m = GetValue(); 那么m的值就一定是5!这就实现了跨进程之间的数据通信!

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

有的时候我们可能想让一个应用程序只启动一次,就像单件模式(singleton)一样,实现的方法可能有多种,这里

说说用#pragma data_seg来实现的方法,很是简洁便利。

应用程序的入口文件前面加上

#pragma data_seg("flag_data")

int app_count = 0;

#pragma data_seg()

#pragma comment(linker,"/SECTION:flag_data,RWS")

然后程序启动的地方加上

if(app_count>0)     // 如果计数大于0,则退出应用程序。

{

//MessageBox(NULL, "已经启动一个应用程序", "Warning", MB_OK);   

//printf("no%d application", app_count);

return FALSE;

}

app_count++;

 

源文档 <http://my.oschina.net/u/218425/blog?disp=2&p=14>

 

 

  1. 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。

Explanation:

First of all, it seems like you passed the function pointer is relative to the pass in.
 Process stack address, and you call the dll, address
 Dll, relative address to be converted,

 

源文档 <http://www.opendebug.com/article/173695>

 

For example, g_pMsgDlgFunc = 07212000;
 When you assign worth to point to the correct address.
 Hook dll is injected into the space of another process, the position may change, this time g_pMsgDlgFunc = 07.212 million points to the address of the process, when you call this address when the hook is not necessarily correct code.
 Do not know you is not the situation. If this call in dll address should be the problem.

 

源文档 <http://www.opendebug.com/article/173695>

 

  1. 终于找到,来看看微软官方的文档。有一句话如下:
  • Classes with virtual functions always contain function pointers. Classes with virtual functions should never be stored in shared data segments nor in memory mapped files. This is particularly important to MFC classes or classes that inherit from MFC.

 

源文档 <http://msdn.microsoft.com/en-us/library/h90dkhs0(VS.80).aspx>

该死心了,不能共享函数指针。

 

最终结论:方案一不可行。

 

转载于:https://www.cnblogs.com/mehale/p/3210636.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值