Отладка (построчно )Rcpp -созданной DLL под Windows

Недавно я экспериментировал со встроенным Rcpp ()для создания библиотек DLL, которые выполняют различные задачи на предоставленных входных данных R. Я хотел бы иметь возможность отлаживать код в этих библиотеках DLL построчно, учитывая определенный набор входных данных R.(Я работаю под Windows.)

Чтобы проиллюстрировать это, давайте рассмотрим конкретный пример, который может запустить любой...

Приведенный ниже код представляет собой действительно простую функцию cxx, которая просто удваивает входной вектор. Обратите внимание, однако, что есть дополнительная переменная myvar, которая меняет значение несколько раз, но не влияет на вывод -, она была добавлена, чтобы мы могли видеть, когда процесс отладки работает правильно.

library(inline)
library(Rcpp)

f0 <- cxxfunction(signature(a="numeric"), plugin="Rcpp", body='
    Rcpp::NumericVector xa(a);
    int myvar = 19;
    int na = xa.size();
    myvar = 27;
    Rcpp::NumericVector out1(na);
    for(int i=0; i < na; i++) {
        out1[i] = 2*xa[i];
        myvar++;
    }
    myvar = 101;
    return(Rcpp::List::create( _["out1"] = out1));
')

После того, как мы запустим вышеуказанное, набрав команду

getLoadedDLLs()

выводит список DLL в сеансе R. Последней в списке должна быть DLL, созданная описанным выше процессом -, она имеет случайное временное имя, которое в моем случае

file7e61645c

Столбец «Имя файла» показывает, что cxxfunction поместил эту DLL в папку tempdir(), которая для меня в настоящее время

C:/Users/TimP/AppData/Local/Temp/RtmpXuxtpa/file7e61645c.dll

. Теперь очевидный способ вызова DLL — через f0следующим образом

> f0(c(-7,0.7,77))

$out1
[1] -14.0   1.4 154.0

Но мы, конечно, также можем вызвать DLL напрямую по имени, используя команду .Call:

>.Call("file7e61645c",c(-7,0.7,77))

$out1
[1] -14.0   1.4 154.0

Итак, я достиг точки, когда я вызываю автономную DLL напрямую с вводом R (здесь, векторомc(-7,0.7,77)), и заставить его вернуть правильный ответ R.

Что мне действительно нужно, так это средство для строки -с помощью -отладки строки (с использованием gdb, я полагаю, ), что позволит мне наблюдать, как значение myvarустановлено на 19, 27, 28, 29, 30 и, наконец, 101 по мере выполнения кода.Приведенный выше пример преднамеренно настроен таким образом, что вызов DLL ничего не говорит нам о myvar.

Чтобы уточнить, «условием победы» здесь является возможность наблюдать за изменением myvar (, видя, что значение myvar=19 будет первым шагом! )ничего не добавляя в тело кода. Это, очевидно, может потребовать изменений в способе компиляции кода (. Есть ли настройки режима отладки, которые нужно включить? ), или как R называется -, но я не знаю, с чего начать. Как отмечалось выше, все это основано на Windows -.

Заключительное замечание :В своих экспериментах я фактически внес некоторые незначительные изменения в копию cxxfunction, чтобы выходная DLL -и код внутри нее -получали определяемое пользователем -имя и располагались в пользовательском -определенный каталог, а не временное имя и местоположение. Но это не меняет сути вопроса. Я упомянул об этом только для того, чтобы подчеркнуть, что изменить настройки компиляции должно быть довольно легко, если кто-то подтолкнет меня:)

Для полноты, установка verbose=TRUE в исходном вызове cxxfunction выше показывает, что аргумент компиляции имеет следующую форму:

C:/R/R-2.13.2/bin/i386/R CMD SHLIB file7e61645c.cpp 2> file7e61645c.cpp.err.txt 
g++ -I"C:/R/R-213~1.2/include"    -I"C:/R/R-2.13.2/library/Rcpp/include"      -O2 -Wall  -c file7e61645c.cpp -o file7e61645c.o
g++ -shared -s -static-libgcc -o file7e61645c.dll tmp.def file7e61645c.o C:/R/R-2.13.2/library/Rcpp/lib/i386/libRcpp.a -LC:/R/R-213~1.2/bin/i386 -lR

Моя адаптированная версия имеет аргумент компиляции, идентичный приведенному выше, за исключением того, что строка «file7e61645c» везде заменяется выбранным пользователем именем (, например. "testdll" )и соответствующие файлы скопированы в более постоянное место.

Заранее спасибо за помощь, ребята:)

20
задан Tim P 5 July 2012 в 13:38
поделиться