Как я получаю HMODULE для в настоящее время выполняющего кода?

Класс Java, который может оценивать математические выражения:

package test;

public class Calculator {

    public static Double calculate(String expression){
        if (expression == null || expression.length() == 0) {
            return null;
        }
        return calc(expression.replace(" ", ""));
    }
    public static Double calc(String expression) {

        if (expression.startsWith("(") && expression.endsWith(")")) {
            return calc(expression.substring(1, expression.length() - 1));
        }
        String[] containerArr = new String[]{expression};
        double leftVal = getNextOperand(containerArr);
        expression = containerArr[0];
        if (expression.length() == 0) {
            return leftVal;
        }
        char operator = expression.charAt(0);
        expression = expression.substring(1);

        while (operator == '*' || operator == '/') {
            containerArr[0] = expression;
            double rightVal = getNextOperand(containerArr);
            expression = containerArr[0];
            if (operator == '*') {
                leftVal = leftVal * rightVal;
            } else {
                leftVal = leftVal / rightVal;
            }
            if (expression.length() > 0) {
                operator = expression.charAt(0);
                expression = expression.substring(1);
            } else {
                return leftVal;
            }
        }
        if (operator == '+') {
            return leftVal + calc(expression);
        } else {
            return leftVal - calc(expression);
        }

    }

    private static double getNextOperand(String[] exp){
        double res;
        if (exp[0].startsWith("(")) {
            int open = 1;
            int i = 1;
            while (open != 0) {
                if (exp[0].charAt(i) == '(') {
                    open++;
                } else if (exp[0].charAt(i) == ')') {
                    open--;
                }
                i++;
            }
            res = calc(exp[0].substring(1, i - 1));
            exp[0] = exp[0].substring(i);
        } else {
            int i = 1;
            if (exp[0].charAt(0) == '-') {
                i++;
            }
            while (exp[0].length() > i && isNumber((int) exp[0].charAt(i))) {
                i++;
            }
            res = Double.parseDouble(exp[0].substring(0, i));
            exp[0] = exp[0].substring(i);
        }
        return res;
    }


    private static boolean isNumber(int c) {
        int zero = (int) '0';
        int nine = (int) '9';
        return (c >= zero && c <= nine) || c =='.';
    }

    public static void main(String[] args) {
        System.out.println(calculate("(((( -6 )))) * 9 * -1"));
        System.out.println(calc("(-5.2+-5*-5*((5/4+2)))"));

    }

}
36
задан pauldoo 17 February 2009 в 20:58
поделиться

4 ответа

HMODULE GetCurrentModule()
{ // NB: XP+ solution!
  HMODULE hModule = NULL;
  GetModuleHandleEx(
    GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
    (LPCTSTR)GetCurrentModule,
    &hModule);

  return hModule;
}
52
ответ дан Serge Wautier 10 October 2019 в 10:17
поделиться

__ImageBase сгенерированный символ компоновщика, который является заголовком DOS модуля (только MSVC). От этого можно бросить его адрес к HINSTANCE или HMODULE. Таким образом, это более удобно, чем прохождение через API.

, Таким образом, просто необходимо сделать это:

EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)

От https://devblogs.microsoft.com/oldnewthing/20041025-00/? p=37483

29
ответ дан heavyd 10 October 2019 в 10:17
поделиться

HMODULE является HINSTANCE, базовый адрес модуля. Так, я видел бы, как это работало. Но если все, что Вы хотите, является HMODULE исполняемого файла, почему бы не перечислить весь HMODULE's в процессе (EnumProcessModules). Одному из них свяжут Ваш .lib в.

ограничение, которое я вижу, - то, что Вы понятия не имеете, из которого DLL или EXE прибывает Ваш .lib. Вы могли бы хотеть сравнить HMODULEs (базовые адреса) с _ReturnAddress, который Вы получаете от своего .lib. Ваш .lib будет принадлежать самому высокому меньшему HMODLUE, чем Ваш _ReturnAddress

-1
ответ дан MSalters 10 October 2019 в 10:17
поделиться

Я посмотрел бы GetModuleHandleEx() использование флага GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS. Похоже, что можно изменить Ваш GetCurrentModule(), чтобы назвать эту стандартную программу вместо VirtualQuery() и передать адрес GetCurrentModule() как lpModuleName аргумент.

ETA:

const HMODULE GetCurrentModule()
{
    DWORD flags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS;
    HMODULE hm = 0;
    ::GetModuleHandleEx( flags, reinterpret_cast<LPCTSTR>( GetCurrentModule ), &hm );   
    return hm;
}

я не попробовал его, но я думаю, что это сделает то, что Вы хотите.

3
ответ дан Rob K 10 October 2019 в 10:17
поделиться