Можно ли обернуть класс c ++ с помощью переменной-члена функцией mex? [Дубликат]

Каждый раз, когда вы получаете ...

"Warning: mysqli_fetch_object () ожидает, что параметр 1 будет mysqli_result, boolean задан«

... это, вероятно, из-за проблемы с вашим запросом. prepare() или query() могут возвращать FALSE (логическое), но это общее сообщение об отказе не оставляет вас в стороне от подсказок. Как вы узнаете, что не так с вашим запросом? Вы задаете !

Прежде всего убедитесь, что сообщения об ошибках включены и видны: добавьте эти две строки в начало файла (ов) сразу после открытия <?php:

error_reporting(E_ALL);
ini_set('display_errors', 1);

Если ваше сообщение об ошибках установлено в php.ini, вам не придется беспокоиться об этом. Просто убедитесь, что вы обрабатываете ошибки изящно и никогда не раскрываете истинные причины каких-либо проблем для ваших пользователей. Выявление истинной причины для общественности может быть приглашением на золото с гравировкой для тех, кто хочет нанести вред вашим сайтам и серверам. Если вы не хотите отправлять ошибки в браузер, вы всегда можете следить за журналами ошибок веб-сервера. Расположение журналов будет варьироваться от сервера к серверу, например, на Ubuntu журнал ошибок обычно находится в /var/log/apache2/error.log. Если вы изучаете журналы ошибок в среде Linux, вы можете использовать tail -f /path/to/log в окне консоли, чтобы видеть ошибки, когда они происходят в режиме реального времени .... или как вы их делаете.

Как только вы 'squared away на стандартном сообщении об ошибках, добавляющем проверку ошибок в вашем соединении с базой данных, и запросы дадут вам гораздо более подробную информацию о проблемах. Посмотрите на этот пример, где имя столбца неверно. Во-первых, код, возвращающий роковое сообщение об ошибке:

$sql = "SELECT `foo` FROM `weird_words` WHERE `definition` = ?";
$query = $mysqli->prepare($sql)); // assuming $mysqli is the connection
$query->bind_param('s', $definition);
$query->execute();

Ошибка является общей и не очень помогает вам в решении того, что происходит.

С помощью пары больше строк кода вы можете получить очень подробную информацию, которую вы можете использовать для решения проблемы сразу . Проверьте утверждение prepare() для правдивости, и если это хорошо, вы можете перейти к привязке и исполнению.

$sql = "SELECT `foo` FROM `weird_words` WHERE `definition` = ?";
if($query = $mysqli->prepare($sql)) { // assuming $mysqli is the connection
    $query->bind_param('s', $definition);
    $query->execute();
    // any additional code you need would go here.
} else {
    $error = $mysqli->errno . ' ' . $mysqli->error;
    echo $error; // 1054 Unknown column 'foo' in 'field list'
}

Если что-то не так, вы можете выплюнуть сообщение об ошибке, которое приведет вас к проблеме , В этом случае в таблице нет столбца foo, решение проблемы тривиально.

Если вы выберете, вы можете включить эту проверку в функцию или класс и расширить ее, обработав ошибки изящно, как упомянутых ранее.

3
задан chappjc 10 November 2015 в 20:13
поделиться

5 ответов

AFAIK, нет простого способа сделать это, потому что интерфейс mexFunction скорее flat . Тем не менее, есть несколько различных обходных решений, о которых я могу думать, что должно помочь вам приблизиться. Выберите лучший вариант в зависимости от ваших потребностей.

  1. Самый простой способ - создать глобальный экземпляр класса dlp в вашей mex-функции. Сделать первый параметр функции mex вызовом строки, которая указывает, какая функция-член глобального объекта должна быть вызвана. Очевидным недостатком является то, что вы превратили вашу mex-функцию в одноэлементный.
  2. Если вам нужно больше одного экземпляра dlp, вы можете создать некоторый глобальный контейнер в функции mex, например std::map<std::string, dlp> , а затем ссылаться на каждый экземпляр dlp с помощью какого-либо имени из MATLAB. Например, для создания нового экземпляра вы вызываете функцию mex с именем, которое еще не существует в map. Затем вы можете вызвать функцию mex с этим именем, строку, указывающую, какую функцию-член вызывать, и любые параметры, которые должны быть переданы в функцию-член. Также настройте какое-то соглашение, по которому вы можете стереть экземпляр dlp из map.
  3. Как и во втором решении, вместо того, чтобы называть экземпляры dlp, вы можете вернуть дескрипторы для каждого экземпляра. Например, создайте глобальный std::set<dlp *>, и если у вас есть функция mex, создайте новый экземпляр dlp, добавьте его в set и верните копию указателя на выделенный объект в MATLAB (вставьте его в скаляр переменная типа mxUINT64_CLASS). Последующие вызовы для вызова функций-членов на этом объекте передают эту переменную handle в функцию mex из MATLAB, вы будете соответствующим образом ее применять в файле mex, найдите ее в set и вызовите функции-члены .

Ни один из этих методов не является особенно красивым, но это единственные способы, с помощью которых я могу вызвать функции-члены класса C ++ из файла mex.

6
ответ дан Praetorian 3 September 2018 в 15:21
поделиться
0
ответ дан Arcturus 3 September 2018 в 15:21
поделиться
1
ответ дан Community 3 September 2018 в 15:21
поделиться

Самый простой способ - создать оболочку MEX, которая хранит экземпляр объекта класса, и отправить вызов этому двоичному файлу MEX. Я создал библиотеку для тех, кто пытается создать MEX-оболочку на C ++.

https://github.com/kyamagu/mexplus

быстрый фрагмент.

// C++ class to be wrapped.
class Database;
// Instance session storage.
template class mexplus::Session<Database>;
// Constructor.
MEX_DEFINE(new) (int nlhs, mxArray* plhs[],
                 int nrhs, const mxArray* prhs[]) {
  InputArguments input(nrhs, prhs, 1);
  OutputArguments output(nlhs, plhs, 1);
  output.set(0, Session<Database>::create(
      new Database(input.get<std::string>(0))));
}
// Destructor.
MEX_DEFINE(delete) (int nlhs, mxArray* plhs[],
                    int nrhs, const mxArray* prhs[]) {
  InputArguments input(nrhs, prhs, 1);
  OutputArguments output(nlhs, plhs, 0);
  Session<Database>::destroy(input.get(0));
}
// Member method.
MEX_DEFINE(query) (int nlhs, mxArray* plhs[],
                   int nrhs, const mxArray* prhs[]) {
  InputArguments input(nrhs, prhs, 2);
  OutputArguments output(nlhs, plhs, 1);
  const Database& database = Session<Database>::getConst(input.get(0));
  output.set(0, database.query(input.get<string>(1)));
}
// And so on...
MEX_DISPATCH
2
ответ дан kyamagu 3 September 2018 в 15:21
поделиться

Вы можете взглянуть на это представление в MATLAB Central. Насколько я знаю, это показывает лучшую практику, разработанную с советами групп новостей от многих, включая MathWorkers.

http://www.mathworks.co.uk/matlabcentral/fileexchange/38964-example-matlab -класс-обертка-для-а-C ++ - класс

4
ответ дан Sam Roberts 3 September 2018 в 15:21
поделиться
Другие вопросы по тегам:

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