Используя классы C++ в .so библиотеках

Чтобы избежать ошибки "models were not all fitted to the same size of dataset", вы должны подгонять обе модели к одному и тому же подмножеству данных. Существует два простых способа сделать это:

  • либо использовать data=glm1$model во второй модели fit
  • , либо получить правильно подмножество набора данных, используя data=na.omit(orig.data[ , all.vars(formula(glm1))]) во втором model fit

Вот пример воспроизводимости с использованием lm (для glm тот же подход должен работать) и update:

# 1st approach
# define a convenience wrapper
update_nested <- function(object, formula., ..., evaluate = TRUE){
    update(object = object, formula. = formula., data = object$model, ..., evaluate = evaluate)
}

# prepare data with NAs
data(mtcars)
for(i in 1:ncol(mtcars)) mtcars[i,i] <- NA

xa <- lm(mpg~cyl+disp, mtcars)
xb <- update_nested(xa, .~.-cyl)
anova(xa, xb)
## Analysis of Variance Table
## 
## Model 1: mpg ~ cyl + disp
## Model 2: mpg ~ disp
##   Res.Df    RSS Df Sum of Sq      F  Pr(>F)  
## 1     26 256.91                              
## 2     27 301.32 -1   -44.411 4.4945 0.04371 *
## ---
## Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

# 2nd approach
xc <- update(xa, .~.-cyl, data=na.omit(mtcars[ , all.vars(formula(xa))]))
anova(xa, xc)
## Analysis of Variance Table
## 
## Model 1: mpg ~ cyl + disp
## Model 2: mpg ~ disp
##   Res.Df    RSS Df Sum of Sq      F  Pr(>F)  
## 1     26 256.91                              
## 2     27 301.32 -1   -44.411 4.4945 0.04371 *
## ---
## Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

См. также:

9
задан frogatto 2 June 2016 в 09:06
поделиться

3 ответа

Классы C++ хорошо работают в совместно использованных библиотеках .so (они также работают в не-MFC DLLs в Windows, но это не действительно Ваш вопрос). Это на самом деле легче, чем Windows, потому что Вы не должны явно экспортировать символы из библиотек.

Этот документ ответит на большинство Ваших вопросов: http://people.redhat.com/drepper/dsohowto.pdf

Главное помнить состоит в том, чтобы использовать -fPIC опция при компиляции, и -shared опция при соединении. Можно найти много примеров в сети.

13
ответ дан 4 December 2019 в 08:54
поделиться

Насколько я понимаю это прекрасно, пока Вы связываете .so файлы, которые были все скомпилированы с помощью того же компилятора. Различные компиляторы искажают символы по-разному и не свяжутся.

Это - одно из преимуществ в использовании COM в Windows, это определяет стандарт для помещения объектов ООП в DLLs. Я могу скомпилировать DLL с помощью GNU g ++ и связать его с EXE, скомпилированным с MSVC - или даже VB!

3
ответ дан 4 December 2019 в 08:54
поделиться

Мое решение/тестирование

Вот мое решение, и оно делает то, что я ожидал.

Код

cat.hh:

#include <string>

class Cat
{
    std::string _name;
public:
    Cat(const std::string & name);
    void speak();
};

cat.cpp:

#include <iostream>
#include <string>

#include "cat.hh"

using namespace std;

Cat::Cat(const string & name):_name(name){}
void Cat::speak()
{
    cout << "Meow! I'm " << _name << endl;
}

main.cpp:

#include <iostream>
#include <string>
#include "cat.hh"

using std::cout;using std::endl;using std::string;
int main()
{
    string name = "Felix";
    cout<< "Meet my cat, " << name << "!" <<endl;
    Cat kitty(name);
    kitty.speak();
    return 0;
}

Компиляция

Вы компилируете общий lib сначала:

$ g++ -Wall -g -fPIC -c cat.cpp
$ g++ -shared -Wl,-soname,libcat.so.1 -o libcat.so.1 cat.o

Затем скомпилируйте основную программу исполняемого или C++ с помощью классов в библиотеках:

$ g++ -Wall -g -c main.cpp
$ g++ -Wall -Wl,-rpath,. -o main main.o libcat.so.1 # -rpath linker option prevents the need to use LD_LIBRARY_PATH when testing
$ ./main
Meet my cat, Felix!
Meow! I'm Felix
$
8
ответ дан 4 December 2019 в 08:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: