如何通过调用另一个DLL文件中的函数来为一个DLL中的变量赋值,该函数将值赋给该变量。 [英] How to get a variable in one DLL assigned a value by calling a function from another DLL file that assigns the value to that variable.

查看:90
本文介绍了如何通过调用另一个DLL文件中的函数来为一个DLL中的变量赋值,该函数将值赋给该变量。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题是:



    如何在一个DLL的函数中定义变量,从另一个DLL文件的被调用函数中获取其值?



=== =============================
$


我正在努力我正在转换为WindowsCE 3.0操作系统编写的代码现在在WindowsCE 6.0操作系统中运行的项目。



因为我在WIndwsCE 3.0中运行正常,我假设在WindowsCE 6.0中尝试做同样的事情时会出现某种不兼容或保护模式问题。


问题是当我执行以下命令时,应用程序崩溃。



在名为Edasapi.DLL的文件中,我执行以下操作:



   ;   INT     fNumIDs;

     #define MOD_COUNT_IDS     1


     err =(* infoFcn)(MOD_COUNT_IDS,& fNumIDs);
$


(其中* infoFcn是一个名为MODULEDESC的函数的指针,名为MODLEDESC,名为anlg_inE已加载的.DLL。)



在名为anlg_inE.DLL的文件中,我执行以下操作:



     #define NUMBER_OF_IDS 2

     MOD_API long MODULEDESC(int code,void * rtn)

     {

         switch(code)     {

             case MOD_COUNT_IDS:

                 *(int *)rtn = NUM​​BER_OF_IDS;

             break;

        }

    }



但是当*(int *)rtn = NUM​​BER_OF_IDS执行时,程序崩溃:



    异常'数据中止'(4):Thread-Id = 05840076(pth = 831dfc88),Proc-Id = 057e0056(p

    prc = 854320c0)'EdasDriver_main。 exe',VM-active = 057e0056(pprc = 854320c0)'EdasDriver_main.exe'

     PC = 40b623e0(anlg_ine.dll + 0x000023e0)RA = 40b623d4(anlg_ine.dll + 0x000023d4)SP = 000

     2f83c,BVA = 00000000



来自EdasapiE.DLL的anlg_inE.DLL中名为MODULEDESC()的函数执行并运行正常。



但是当遇到命令时(*(int *)rtn = NUM​​BER_OF_IDS; ),程序崩溃。



EdasapiE.DLL中的变量'fNumIDs'需要被赋予一个值,该值在调用名为MODlEDESC()的函数时被定义,该函数名为anlg_inE.DLL。


似乎与EdasapiE.DLL中传递的'& fNumIDs'地址与anlg_inE.DLL中MODULEDESC()函数中的*(int *)rtn变量有冲突。


我期待  *(int *)rtn指向'fNumIDs'的地址,然后将NUMBER_OF_IDS的值分配给'fNumIDs'变量。 但是应用程序崩溃在'*(int *)rtn = NUM​​BER_OF_IDS;'命令。



在WindowsCE 6.0中,我可以,或者我如何通过该地址DLL(EdasapiE.DLL)的一个函数(nsSWinit)中的变量(fNumIDs)到另一个DLL(anlg_inE.DLL)中的另一个函数(MODULEDESC),它为该变量赋值(NUMBER_OF_IDS)(fNumIDs ... ie ..
*(int *)rtn)?



=================== ====================================
$


更多细节。



我运行一个名为EdasDriver_main.exe的程序,该程序在OS系统首次启动时启动。

(即使我手动运行程序我得到相同的结果)。



EdasDriver_main.exe执行LoadLibrary()命令,该命令加载到名为EdasapiE.DLL的DLL中。


$
EdasDriver_main.exe然后执行GetProcessAddress()命令来运行位于 的函数。 EdasAPI.DLL调用nsHWInit()。



nsHWInit()执行一些硬件初始化运行一个名为nsSWInit()的函数。



nsSWInit()执行的许多操作之一是加载它在特定文件夹中找到的所有.DLL文件。

在这种情况下,它首先找到一个名为anlg_inE的文件.DLL  然后nsSWInit()执行LoadLibrary()命令以加载anlg_inE.DLL文件。



     typedef long(* DescFunction)(int code,void * rtn);

    HINSTANCE     fInstanceHandle;

     DescFunction     infoFcn;



     infoFcn =(DescFunction)GetProcAddress(fInstanceHandle,MAKEINTRESOURCE(2));


(MAKEINTRESOURCE(2)被解码为anlg_inE.DLL文件中的MODULEDESC()函数。)


(然后我从EdasapiE.DLL调用anlg_inE.DLL中的MODULEDESC()函数)


// MOD_COUNT_IDS ...模块类型数。$
// fNumIDs是一个在MODULEDESC例程中填写的记忆位置。


    err =(* infoFcn)(MOD_COUNT_IDS,& fNumIDs);

     if(err)

     {

         RETAILMSG(1,(TEXT(" FAIL ===== FcnDLL :: GetModuleInfo ... MOD_COUNT_IDS.\\ nn))));

         return err;

    }



(位于名为MODULEDESC()的anlg_inE.DLL文件中的函数执行。)



     MOD_API long MODULEDESC(int code,void * rtn)

     {

         switch(code)     {

             case MOD_COUNT_IDS:

                 *(int *)rtn = NUM​​BER_OF_IDS;

             break;

        }

    }



$
名为MODULEDESC的函数接收两个输入参数,一个名为"code"(MOD_COUNT_IDS)的参数,以及fNumIDs(void * rtn)。 我没有收到编译错误或警告。



所以从EdasAPIE.DLL代码我加载到名为anlg_INE.DLL的文件中,然后从EdasaoiE.DLL加载,运行一个名为MODULEDESC的函数位于anlg_inE.FLL文件中。


$
但是*(int *)rtn = NUM​​BER_OF_IDS;执行时崩溃。



再次,这个原始代码编写并在WindowsCE 3.0中正常运行,但我需要它在WindowsCE 6.0中工作


关于为什么会发生这种情况的任何建议并且要解决它?...谢谢


       

解决方案

您可能需要编组指针,尽管在这种情况下它不是嵌入式指针,因此它应该已经被编组了。但是,这仅在您从用户调用内核模式时才有效。你在调用用户到用户模式的DLL,是
其中一个用户模式和另一个内核模式,还是它们都是内核模式DLL?请查看 http://msdn.microsoft.com/en-us/library/jj659784.aspx 了解更多信息和理解。


如果你正在编写C ++代码,你可以使用包装类
MarshalledBuffer_t
让您的生活更轻松。




The question is:

    How can I get a variable defined in a function of one DLL, to get assigned its value from a called function of a different DLL file?

================================

I am working on a project where I am transposing code written for a WindowsCE 3.0 operating system to now run in a WindowsCE 6.0 operating system.

Since what I have runs ok in WIndwsCE 3.0, I presume that there is some kind of incompatibility or protective mode issues when trying to do the same thing in WindowsCE 6.0

The problem is that when I execute the following command, the application crashes.

In a file called Edasapi.DLL I execute the following:

    int    fNumIDs;
    #define MOD_COUNT_IDS    1

    err = (*infoFcn) (MOD_COUNT_IDS, &fNumIDs);

(where *infoFcn is the pointer to a function called MODULEDESC in a DLL file called anlg_inE.DLL that has already been loaded in.)

In the file called anlg_inE.DLL I do the following:

    #define NUMBER_OF_IDS 2
    MOD_API long MODULEDESC (int code, void *rtn)
    {
        switch (code)    {
            case MOD_COUNT_IDS:
                *(int *)rtn = NUMBER_OF_IDS;
            break;
        }
    }

But when *(int *)rtn = NUMBER_OF_IDS executes, the program crashes:

    Exception 'Data Abort' (4): Thread-Id=05840076(pth=831dfc88), Proc-Id=057e0056(p
    prc=854320c0) 'EdasDriver_main.exe', VM-active=057e0056(pprc=854320c0) 'EdasDriver_main.exe'
    PC=40b623e0(anlg_ine.dll+0x000023e0) RA=40b623d4(anlg_ine.dll+0x000023d4) SP=000
    2f83c, BVA=00000000

The function called MODULEDESC() located in anlg_inE.DLL from the EdasapiE.DLL does execute and run ok.

But when the command is encountered( *(int *)rtn = NUMBER_OF_IDS;  ), the program crashes.

The variable 'fNumIDs' in EdasapiE.DLL need to get assigned a value that gets defined when calling a function called MODULEDESC() in the file called anlg_inE.DLL

There seems to be a conflict with the passed address of '&fNumIDs' from EdasapiE.DLL to the *(int *)rtn variable in the MODULEDESC() function in anlg_inE.DLL.

I expect  *(int *)rtn is be pointing to the address of 'fNumIDs' and then assigning the value of NUMBER_OF_IDS to 'fNumIDs' variable.  But instead the application crashes at the ' *(int *)rtn = NUMBER_OF_IDS;' command.

In WindowsCE 6.0, can I, or how can I pass the address of a variable(fNumIDs) in one function(nsSWinit) of a DLL(EdasapiE.DLL) to another function(MODULEDESC) in a different DLL(anlg_inE.DLL) which assigns a value(NUMBER_OF_IDS) to that variable(fNumIDs...i.e... *(int *)rtn)?

=======================================================

More details.

I run a program called EdasDriver_main.exe that starts when the OS system first boots up.
(Even if I run the program manually I get the same results).

EdasDriver_main.exe executes a LoadLibrary() command which loads in a DLL called EdasapiE.DLL.

EdasDriver_main.exe then performs a GetProcessAddress() command to run a function located in the  EdasAPI.DLL called nsHWInit().

nsHWInit() performs some hardware initialzation the runs a function called nsSWInit().

One of the many things that nsSWInit() performs is to load in all .DLL files it finds in a specific folder.
In this case, it first finds a file called anlg_inE.DLL.   nsSWInit() then executes a LoadLibrary() command to load in the anlg_inE.DLL file.

    typedef long (*DescFunction) (int code, void *rtn);
    HINSTANCE    fInstanceHandle;
    DescFunction    infoFcn;

    infoFcn = (DescFunction)GetProcAddress (fInstanceHandle, MAKEINTRESOURCE(2));

(MAKEINTRESOURCE(2) gets decoded to be the function MODULEDESC() in the anlg_inE.DLL file.)

(I then call the MODULEDESC() function in anlg_inE.DLL from EdasapiE.DLL)

// MOD_COUNT_IDS ... Number of Module types.
// fNumIDs is a memory location that gets filled in the MODULEDESC routine.

    err = (*infoFcn) (MOD_COUNT_IDS, &fNumIDs);
    if (err)
    {
        RETAILMSG(1,(TEXT("FAIL ===== FcnDLL::GetModuleInfo...MOD_COUNT_IDS.\r\n")));
        return err;
    }

(The function located in the anlg_inE.DLL file called MODULEDESC() executes.)

    MOD_API long MODULEDESC (int code, void *rtn)
    {
        switch (code)    {
            case MOD_COUNT_IDS:
                *(int *)rtn = NUMBER_OF_IDS;
            break;
        }
    }


The function called MODULEDESC receives two input parameters, a parameter called 'code'( MOD_COUNT_IDS), and the address of fNumIDs(void *rtn).  I get no compile errors or warnings.

So from the EdasAPIE.DLL code I am loading in the file called anlg_INE.DLL and then from EdasaoiE.DLL, running a function called MODULEDESC located in the anlg_inE.FLL file.

But *(int *)rtn = NUMBER_OF_IDS; crashes when it executes.

Again, this original code was written and runs fine in WindowsCE 3.0, but I need it to work in WindowsCE 6.0

Any advice on why this happens and hw to fix it?...Thanks

       

解决方案

You probably need to marshal the pointer, although in this case it's not an embedded pointer so it should have been marshaled already. However, this is only valid in case you are calling from user to kernel mode. Are you calling user to user mode DLLs, is one of them user mode and the other kernel mode, or are they both kernel mode DLLs? Have a look at http://msdn.microsoft.com/en-us/library/jj659784.aspx for more information and understanding.

If you're writing C++ code you can use the wrapper class MarshalledBuffer_t to make your life easier.


这篇关于如何通过调用另一个DLL文件中的函数来为一个DLL中的变量赋值,该函数将值赋给该变量。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆