I'm facing a tough problem adding the static library libengine.lib from Matlab to a neq QT project.
As I read from some blogs, I have to include both the engine.h header and the libengine.lib library to the .pro file. But when I build and run the project it seems that QT is not able to find the engOpen function of the library.
Here is my (basic) code. classe file is, for now, an empty class. The main.cpp file contains example code which is taken from Matlab tutorial, so I guess it is not a problem.
//.pro file
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = Progetto
TEMPLATE = app
CONFIG += staticlib
SOURCES += main.cpp\
classe.cpp
FORMS += classe.ui
INCLUDEPATH += "C:/Users/Zeno/Desktop/M_libraries"
LIBS += "C:/Users/Zeno/Desktop/M_libraries/libeng.lib"
HEADERS += classe.h \
../../M_libraries/engine.h
//main.cpp
#include "classe.h"
#include <QApplication>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "engine.h"
#define BUFSIZE 256
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Engine *ep;
mxArray *T = NULL, *result = NULL;
char buffer[BUFSIZE+1];
double time[10] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 };
/*
* Call engOpen with a NULL string. This starts a MATLAB process
* on the current host using the command "matlab".
*/
if (!(ep = engOpen(""))) {
fprintf(stderr, "\nCan't start MATLAB engine\n");
return EXIT_FAILURE;
}
/*
* PART I
*
* For the first half of this demonstration, we will send data
* to MATLAB, analyze the data, and plot the result.
*/
/*
* Create a variable for our data
*/
T = mxCreateDoubleMatrix(1, 10, mxREAL);
memcpy((void *)mxGetPr(T), (void *)time, sizeof(time));
/*
* Place the variable T into the MATLAB workspace
*/
engPutVariable(ep, "T", T);
/*
* Evaluate a function of time, distance = (1/2)g.*t.^2
* (g is the acceleration due to gravity)
*/
engEvalString(ep, "D = .5.*(-9.8).*T.^2;");
/*
* Plot the result
*/
engEvalString(ep, "plot(T,D);");
engEvalString(ep, "title('Position vs. Time for a falling object');");
engEvalString(ep, "xlabel('Time (seconds)');");
engEvalString(ep, "ylabel('Position (meters)');");
/*
* use fgetc() to make sure that we pause long enough to be
* able to see the plot
*/
printf("Hit return to continue\n\n");
fgetc(stdin);
/*
* We're done for Part I! Free memory, close MATLAB figure.
*/
printf("Done for Part I.\n");
mxDestroyArray(T);
engEvalString(ep, "close;");
/*
* PART II
*
* For the second half of this demonstration, we will request
* a MATLAB string, which should define a variable X. MATLAB
* will evaluate the string and create the variable. We
* will then recover the variable, and determine its type.
*/
/*
* Use engOutputBuffer to capture MATLAB output, so we can
* echo it back. Ensure first that the buffer is always NULL
* terminated.
*/
buffer[BUFSIZE] = '\0';
engOutputBuffer(ep, buffer, BUFSIZE);
while (result == NULL) {
char str[BUFSIZE+1];
/*
* Get a string input from the user
*/
printf("Enter a MATLAB command to evaluate. This command should\n");
printf("create a variable X. This program will then determine\n");
printf("what kind of variable you created.\n");
printf("For example: X = 1:5\n");
printf(">> ");
fgets(str, BUFSIZE, stdin);
/*
* Evaluate input with engEvalString
*/
engEvalString(ep, str);
/*
* Echo the output from the command.
*/
printf("%s", buffer);
/*
* Get result of computation
*/
printf("\nRetrieving X...\n");
if ((result = engGetVariable(ep,"X")) == NULL)
printf("Oops! You didn't create a variable X.\n\n");
else {
printf("X is class %s\t\n", mxGetClassName(result));
}
}
/*
* We're done! Free memory, close MATLAB engine and exit.
*/
printf("Done!\n");
mxDestroyArray(result);
engClose(ep);
return EXIT_SUCCESS;
Classe w;
w.show();
return a.exec();
}
This is the error I face:
undefined reference to 'engOpen' in main.cpp
Related
I have created with GIMP a C-Source image dump like the following:
/* GIMP RGBA C-Source image dump (example.c) */
static const struct {
guint width;
guint height;
guint bytes_per_pixel; /* 2:RGB16, 3:RGB, 4:RGBA */
guint8 pixel_data[304 * 98 * 2 + 1];
} example= {
304, 98, 2,
"\206\061\206\061..... }
Is there a way to read this in GIMP again in order to get back the original image? because it doesn't seem possible.
Or does it exist a tool that can do this back-conversion?
EDITED
Following some suggestion I tried to write a simple C programme to make the reverse coversion ending up with something very similar to another code found on internet but both dont work:
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "imgs_press.h"
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
using namespace std;
int main(int argc, char** argv) {
int fd;
char *name = "orignal_img.pnm";
fd = open(name, O_WRONLY | O_CREAT, 0644);
if (fd == -1) {
perror("open failed");
exit(1);
}
if (dup2(fd, 1) == -1) {
perror("dup2 failed");
exit(1);
}
// file descriptor 1, i.e. stdout, now points to the file
// "helloworld" which is open for writing
// You can now use printf which writes specifically to stdout
printf("P2\n");
printf("%d %d\n", press_high.width, press_high.height);
for(int x=0; x<press_high.width * press_high.height * 2; x++) {
printf("%d ", press_high.pixel_data[x]);
}
}
As suggested by n-1-8e9-wheres-my-share-m, maybe I need to manipulate the pixels usign the correct decode, but I have no idea how to do that, does anybody have other suggestions?
The image I got is indeed distorted:
Updated Answer
If you want to decode the RGB565 and write a NetPBM format PNM file without using ImageMagick, you can do this:
#include <stdint.h> /* for uint8_t */
#include <stdio.h> /* for printf */
/* tell compiler what those GIMP types are */
typedef int guint;
typedef uint8_t guint8;
#include <YOURGIMPIMAGE>
int main(){
int w = gimp_image.width;
int h = gimp_image.height;
int i;
uint16_t* RGB565p = (uint16_t*)&(gimp_image.pixel_data);
/* Print P3 PNM header on stdout */
printf("P3\n%d %d\n255\n",w, h);
/* Print RGB pixels, ASCII, one RGB pixel per line */
for(i=0;i<w*h;i++){
uint16_t RGB565 = *RGB565p++;
uint8_t r = (RGB565 & 0xf800) >> 8;
uint8_t g = (RGB565 & 0x07e0) >> 3;
uint8_t b = (RGB565 & 0x001f) << 3;
printf("%d %d %d\n", r, g ,b);
}
}
Compile with:
clang example.c
And run with:
./a.out > result.pnm
I have not tested it too extensively beyond your sample image, so you may want to make a test image with some reds, greens, blues and shades of grey to ensure that all my bit-twiddling is correct.
Original Answer
The easiest way to get your image back would be... to let ImageMagick do it.
So, take your C file and add a main() to it that simply writes the 304x98x2 bytes starting at &(example.pixel_data) to stdout:
Compile it with something like:
clang example.c -o program # or with GCC
gcc example.c -o program
Then run it, writing to a file for ImageMagick with:
./program > image.bin
And tell ImageMagick its size, type and where it is and what you want as a result:
magick -size 304x98 RGB565:image.bin result.png
I did a quick, not-too-thorough test of the following code and it worked fine for an image I generated with GIMP. Note it doesn't handle alpha/transparency but that could be added if necessary. Save it as program.c:
#include <unistd.h> /* for write() */
#include <stdint.h> /* for uint8_t */
/* tell compiler what those GIMP types are */
typedef int guint;
typedef uint8_t guint8;
<PASTE YOUR GIMP FILE HERE>
int main(){
/* Work out how many bytes to write */
int nbytes = example.width * example.height * 2;
/* Write on stdout for redirection to a file - may need to reopen in binary mode if on Windows */
write(1, &(example.pixel_data), nbytes);
}
If I run this with the file you provided via Google Drive I get:
Is there a fallocate() equivalent in OS X?
I would like to aggregate all of those equivalent in OS X questions into some doc/table or whatever for everyone. Anybody knows something familiar?
What about using:
mkfile -n 1m test.tmp
It's not the same command but serves the same purpose.
Note that fallocate uses decimal multipliers, whereas mkfile uses binary multipliers.
mkfile man
fallocate() doesn't exist on OSX. You can "fake" it though; Mozilla fakes it in their FileUtils class. See this file:
http://hg.mozilla.org/mozilla-central/file/3d846420a907/xpcom/glue/FileUtils.cpp#l61
Here's the code, in case that link goes stale:
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla code.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Taras Glek <tglek#mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#if defined(XP_UNIX)
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#elif defined(XP_WIN)
#include <windows.h>
#endif
#include "nscore.h"
#include "private/pprio.h"
#include "mozilla/FileUtils.h"
bool
mozilla::fallocate(PRFileDesc *aFD, PRInt64 aLength)
{
#if defined(HAVE_POSIX_FALLOCATE)
return posix_fallocate(PR_FileDesc2NativeHandle(aFD), 0, aLength) == 0;
#elif defined(XP_WIN)
return PR_Seek64(aFD, aLength, PR_SEEK_SET) == aLength
&& 0 != SetEndOfFile((HANDLE)PR_FileDesc2NativeHandle(aFD));
#elif defined(XP_MACOSX)
int fd = PR_FileDesc2NativeHandle(aFD);
fstore_t store = {F_ALLOCATECONTIG, F_PEOFPOSMODE, 0, aLength};
// Try to get a continous chunk of disk space
int ret = fcntl(fd, F_PREALLOCATE, &store);
if(-1 == ret){
// OK, perhaps we are too fragmented, allocate non-continuous
store.fst_flags = F_ALLOCATEALL;
ret = fcntl(fd, F_PREALLOCATE, &store);
if (-1 == ret)
return false;
}
return 0 == ftruncate(fd, aLength);
#elif defined(XP_UNIX)
// The following is copied from fcntlSizeHint in sqlite
/* If the OS does not have posix_fallocate(), fake it. First use
** ftruncate() to set the file size, then write a single byte to
** the last byte in each block within the extended region. This
** is the same technique used by glibc to implement posix_fallocate()
** on systems that do not have a real fallocate() system call.
*/
struct stat buf;
int fd = PR_FileDesc2NativeHandle(aFD);
if (fstat(fd, &buf))
return false;
if (buf.st_size >= aLength)
return false;
const int nBlk = buf.st_blksize;
if (!nBlk)
return false;
if (ftruncate(fd, aLength))
return false;
int nWrite; // Return value from write()
PRInt64 iWrite = ((buf.st_size + 2 * nBlk - 1) / nBlk) * nBlk - 1; // Next offset to write to
do {
nWrite = 0;
if (PR_Seek64(aFD, iWrite, PR_SEEK_SET) == iWrite)
nWrite = PR_Write(aFD, "", 1);
iWrite += nBlk;
} while (nWrite == 1 && iWrite < aLength);
return nWrite == 1;
#endif
return false;
}
For those wanting to create fake data files for testing, mkfile is pretty elegant. An alternative is to use dd:
dd if=/dev/zero of=zfile count=1024 bs=1024
As you can see with od -b zfile, it's full of zeros. If you want random data (which you may want for testing workflows with data compression, for example), then use "/dev/random" in place of "/dev/zero":
dd if=/dev/random of=randfile count=1024 bs=1024
I am working on a large project in C++ that is proprietary, so I can't actually share the source code. I have most of the code compiled, but there is one function, in a particular file, that is giving me quite a bit of trouble.
I've created a simple example that shows what the problem is. We have:
WTPSHORT.H
#ifndef WTP_H
#define WTP_H 1
#define VERSION "Version 2.1"
#define DATE "Nov., 2001"
/* ANSI C header files */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <fcntl.h>
#include <ctype.h>
#define TRUE 1
#define FALSE 0
/************ Data structures for Water Treatment Plant ***************/
struct Effluent { /****** Data Packet for All Unit Processes *******/
/* Operating data: */
double DegK; /* Temperature (Deg K) */
double Flow; /* Average flow (MGD) */
double Peak; /* Max hourly flow (MDG) */
/* Unit process counters: */
short cl2cnt; /* Number of times chlorine added. */
/* Measurable Water Quality Parameters: */
double pH; /* [H+]=pow(10,-pH) (-) */
/* More variable definitions go here */
double beta_br; /* Constant for chlorine to bromine reactivity ratio */
double time_step; /* Time step (hrs) */
}; /************ End of struct Effluent ************/
/*****************************************/
struct ProcessTrain { /* Control Structure for Process Train */
struct UnitProcess *head; /* First UnitProcess in ProcessTrain */
struct UnitProcess *null; /* Always NULL */
struct UnitProcess *tail; /* Last UnitProcess in ProcessTrain */
char file_name[120]; /* Full path and extension */
}; /*****************************************/
struct UnitProcess { /********** Treatment Process ***************/
struct UnitProcess *next; /* Double Linked list */
struct UnitProcess *prev; /* " " " */
short type; /* Defined unit process types */
short pad; /* Maintain 32 bit alinment of pointers */
union { /* Design and operating parameters: */
void *ptr;
struct Influent *influent;
struct Mechdbp *mechdbp; //FOR MECH MODEL
struct Alum *alum;
struct Gac *gac;
struct Filter *filter;
struct Basin *basin;
// struct Membrane *membrane;
struct Mfuf *mfuf;
struct Nf *nf;
struct Iron *iron;
struct chemical *chemical;
struct clo2 *clo2;
struct lime *lime;
/*struct WTP_effluent *wtp_effluent; No longer needed - WJS, 11/98 */
struct Avg_tap *avg_tap;
struct End_of_system *end_of_system;
} data;
struct Effluent eff;
};
struct Influent { /* Raw Water Data */
double pH; /* (-) */
double temp; /* Average temperature (C) */
double low_temp; /* Low temperature for disinfection (C) */
double toc; /* (mg/L) */
double uv254; /* (1/cm) */
double bromide; /* (mg/L) */
double alkalinity; /* (mg/L as CaCO3) */
double calcium; /* Calcium Hardness (mg/L as CaCO3) */
double hardness; /* Total Hardness (mg/L as CaCO3) */
double nh3; /* Ammonia (mg/L as N) */
double ntu; /* Turbidity */
double crypto_req; /* Crypto Log removal + Log Inact. required*/
double clo2_crypto_ct_mult; /* Multiplier */
double peak_flow; /* Peak Hourly Flow for disinfection (MGD) */
double avg_flow; /* Average Flow (MGD) */
int swflag; /* TRUE=Surface Water; FALSE=Ground Water */
// char *run_name;
};
void s1_s2_est(struct UnitProcess *unit);
/* define(s) for UnitProcess.type */
#define VACANT 0
#define INFLUENT 1
#define RAPID_MIX 2
#define SLOW_MIX 3
#define SETTLING_BASIN 4
#define FILTER 5
#define BASIN 6
#define CONTACT_TANK 7
#define CLEARWELL 8
#define O3_CONTACTOR 9
#define GAC 10
#define MFUF_UP 11
#define NF_UP 12
#endif
And then there are two source files in the project:
s1s2_est.c
/* s1s2_est.c -- December, 2000*/
#include "WTPSHORT.H"
void s1_s2_est(struct UnitProcess *unit)
{
double toc, uva, s1_0, s2h_0, s2star_0, s2t_0, s1_f, s2h_f, s2star_f, s2t_f, H;
struct Effluent *eff;
eff = &unit->eff;
/* Get these inputs */
toc = eff->TOC;
uva = eff->UV;
s1_0 = eff->s1;
s2h_0 = eff->s2h;
s2star_0 = eff->s2_star;
H = pow(10.0, -eff->pH);
s2t_0 = s2h_0 + s2star_0;
s1_f = s1_0;
s2t_f = s2t_0;
s2star_f = s2star_0;
s2h_f = s2h_0;
if(eff->s1_s2_estflag == 'C')
{
/* Safety check */
if (toc < 0.0) toc = 0.0;
if (uva < 0.0) uva = 0.0;
s1_f = 5.05 * pow(toc, 0.57) * pow(uva, 0.54);
s2t_f = 13.1 * pow(toc, 0.38) * pow(uva, 0.40);
/* No increases in the S values allowed */
if(s1_f > s1_0 ) s1_f = s1_0;
if(s2t_f > s2t_0) s2t_f = s2t_0;
/* Speciate S2 */
s2h_f = s2t_f * eff->k21r * H / (eff->k21f + eff->k21r * H);
s2star_f = s2t_f * eff->k21f / (eff->k21f + eff->k21r * H);
}
if(eff->s1_s2_estflag != 'C' && unit->type == INFLUENT)
{/* Speciate S2 in raw water*/
s2h_f = s2t_f * eff->k21r * H / (eff->k21f + eff->k21r * H);
s2star_f = s2t_f * eff->k21f / (eff->k21f + eff->k21r * H);
}
/* Update Effluent data structure */
eff->s1 = s1_f;
eff->s2h = s2h_f;
eff->s2_star = s2star_f;
}/* End subroutine "s1_s2_est()"*/
and then
main.cpp
#include <stdio.h>
#include "WTPSHORT.H"
int main(int argc, char **argv)
{
UnitProcess *myunit;
s1_s2_est(myunit);
printf("done\n");
return 0;
}
When compiling and linking I see this error:
C:\WINDOWS\system32\cmd.exe /C "C:/MinGW/bin/mingw32-make.exe -j8 SHELL=cmd.exe -e -f Makefile"
"----------Building project:[ simple - Debug ]----------"
mingw32-make.exe[1]: Entering directory 'C:/Users/joka0958/Desktop/wtp/compiledwtp/simple'
C:/MinGW/bin/g++.exe -c "C:/Users/joka0958/Desktop/wtp/compiledwtp/simple/main.cpp" -g -O0 -Wall -o ./Debug/main.cpp.o -I. -I.
C:/MinGW/bin/gcc.exe -c "C:/Users/joka0958/Desktop/wtp/compiledwtp/simple/s1s2_est.c" -g -O0 -Wall -o ./Debug/s1s2_est.c.o -I. -I.
C:/Users/joka0958/Desktop/wtp/compiledwtp/simple/main.cpp: In function 'int main(int, char**)':
C:/Users/joka0958/Desktop/wtp/compiledwtp/simple/main.cpp:7:22: warning: 'myunit' is used uninitialized in this function [-Wuninitialized]
s1_s2_est(myunit);
^
C:/MinGW/bin/g++.exe -o ./Debug/simple #"simple.txt" -L.
./Debug/main.cpp.o: In function `main':
C:/Users/joka0958/Desktop/wtp/compiledwtp/simple/main.cpp:7: undefined reference to `s1_s2_est(UnitProcess*)'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[1]: [Debug/simple] Error 1
mingw32-make.exe: [All] Error 2
simple.mk:78: recipe for target 'Debug/simple' failed
mingw32-make.exe[1]: Leaving directory 'C:/Users/joka0958/Desktop/wtp/compiledwtp/simple'
Makefile:4: recipe for target 'All' failed
2 errors, 1 warnings
So the question is: Why am I getting an undefined reference?
I realize this is one of those errors that probably masks another problem, but I have really exhausted all possibilities, in my mind, of what could be causing the problem. Note that this is part of a larger project where many other functions compile and link properly.
By the way I am using Codelite with the MinGW compiler on Windows 10.
I'm sorry for all the consternation this question caused. It turns out that there was C++-specific functions within this file, but because the file was named with a *.c, codelite defaulted to the C compiler to actually compile this particular source file. Once I changed the filename, the code compiled successfully. Thanks for all of your useful suggestions!
I'm trying to use nordic semiconductor example showing how to use button handling library: https://github.com/NordicSemiconductor/nrf51-app-button-example
compiler gives me error like in the title. I'm trying to find missing coma or semicolon but I can't see any mistake.
app_error.c
/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
*/
/** #file
*
* #defgroup app_error Common application error handler
* #{
* #ingroup app_common
*
* #brief Common application error handler.
*/
#include "nrf.h"
#include "app_error.h"
#include "compiler_abstraction.h"
#include "nordic_common.h"
#ifdef DEBUG
#include "bsp.h"
/* global error variables - in order to prevent removal by optimizers */
uint32_t m_error_code;
uint32_t m_line_num;
const uint8_t * m_p_file_name;
#endif
/**#brief Function for error handling, which is called when an error has occurred.
*
* #warning This handler is an example only and does not fit a final product. You need to analyze
* how your product is supposed to react in case of error.
*
* #param[in] error_code Error code supplied to the handler.
* #param[in] line_num Line number where the handler is called.
* #param[in] p_file_name Pointer to the file name.
*
* Function is implemented as weak so that it can be overwritten by custom application error handler
* when needed.
*/
/*lint -save -e14 */
__WEAK void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name)
{
// On assert, the system can only recover with a reset.
#ifndef DEBUG
NVIC_SystemReset();
#else
#ifdef BSP_DEFINES_ONLY
LEDS_ON(LEDS_MASK);
#else
UNUSED_VARIABLE(bsp_indication_set(BSP_INDICATE_FATAL_ERROR));
// This call can be used for debug purposes during application development.
// #note CAUTION: Activating this code will write the stack to flash on an error.
// This function should NOT be used in a final product.
// It is intended STRICTLY for development/debugging purposes.
// The flash write will happen EVEN if the radio is active, thus interrupting
// any communication.
// Use with care. Uncomment the line below to use.
//ble_debug_assert_handler(error_code, line_num, p_file_name);
#endif // BSP_DEFINES_ONLY
m_error_code = error_code;
m_line_num = line_num;
m_p_file_name = p_file_name;
UNUSED_VARIABLE(m_error_code);
UNUSED_VARIABLE(m_line_num);
UNUSED_VARIABLE(m_p_file_name);
__disable_irq();
while(1) ;
#endif // DEBUG
}
/*lint -restore */
app_error.h
/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
*
* The information contained herein is property of Nordic Semiconductor ASA.
* Terms and conditions of usage are described in detail in NORDIC
* SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
*
* Licensees are granted free, non-transferable use of the information. NO
* WARRANTY of ANY KIND is provided. This heading must NOT be removed from
* the file.
*
*/
/** #file
*
* #defgroup app_error Common application error handler
* #{
* #ingroup app_common
*
* #brief Common application error handler and macros for utilizing a common error handler.
*/
#ifndef APP_ERROR_H__
#define APP_ERROR_H__
#include <stdint.h>
#include <stdbool.h>
#include "nrf_error.h"
/**#brief Function for error handling, which is called when an error has occurred.
*
* #param[in] error_code Error code supplied to the handler.
* #param[in] line_num Line number where the handler is called.
* #param[in] p_file_name Pointer to the file name.
*/
void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name);
/**#brief Macro for calling error handler function.
*
* #param[in] ERR_CODE Error code supplied to the error handler.
*/
#ifdef DEBUG
#define APP_ERROR_HANDLER(ERR_CODE) \
do \
{ \
app_error_handler((ERR_CODE), __LINE__, (uint8_t*) __FILE__); \
} while (0)
#else
#define APP_ERROR_HANDLER(ERR_CODE) \
do \
{ \
app_error_handler((ERR_CODE), 0, 0); \
} while (0)
#endif
/**#brief Macro for calling error handler function if supplied error code any other than NRF_SUCCESS.
*
* #param[in] ERR_CODE Error code supplied to the error handler.
*/
#define APP_ERROR_CHECK(ERR_CODE) \
do \
{ \
const uint32_t LOCAL_ERR_CODE = (ERR_CODE); \
if (LOCAL_ERR_CODE != NRF_SUCCESS) \
{ \
APP_ERROR_HANDLER(LOCAL_ERR_CODE); \
} \
} while (0)
/**#brief Macro for calling error handler function if supplied boolean value is false.
*
* #param[in] BOOLEAN_VALUE Boolean value to be evaluated.
*/
#define APP_ERROR_CHECK_BOOL(BOOLEAN_VALUE) \
do \
{ \
const uint32_t LOCAL_BOOLEAN_VALUE = (BOOLEAN_VALUE); \
if (!LOCAL_BOOLEAN_VALUE) \
{ \
APP_ERROR_HANDLER(0); \
} \
} while (0)
#endif // APP_ERROR_H__
/** #} */
main.c
**********************************************************************/
#include "nrf.h"
#include "ble.h"
#include <stdbool.h>
#include <string.h>
#include "app_button.h"
#include "boards.h"
#include "app_gpiote.h"
#include "app_timer.h"
#include "pca10028.h"
#define APP_TIMER_PRESCALER 0 // Value of the RTC1 PRESCALER register.
#define APP_TIMER_MAX_TIMERS 1 // Maximum number of simultaneously created timers.
#define APP_TIMER_OP_QUEUE_SIZE 2 // Size of timer operation queues.
#define BUTTON_DEBOUNCE_DELAY 50 // Delay from a GPIOTE event until a button is reported as pushed.
#define APP_GPIOTE_MAX_USERS 1 // Maximum number of users of the GPIOTE handler.
/*
* Handler to be called when button is pushed.
* param[in] pin_no The pin number where the event is genereated
* param[in] button_action Is the button pushed or released
*/
static void button_handler(uint8_t pin_no, uint8_t button_action)
{
if(button_action == APP_BUTTON_PUSH)
{
switch(pin_no)
{
case BUTTON_1:
nrf_gpio_pin_toggle(LED_1);
break;
case BUTTON_2:
nrf_gpio_pin_toggle(LED_2);
break;
case BUTTON_3:
nrf_gpio_pin_toggle(LED_3);
break;
case BUTTON_4:
nrf_gpio_pin_toggle(LED_4);
break;
default:
break;
}
}
}
/**
* Initialize the clock.
*/
void init_clock()
{
NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
NRF_CLOCK->TASKS_LFCLKSTART = 1;
while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0); // Wait for clock to start
}
/**
* Initialize all four LEDs on the nRF51 DK.
*/
void init_leds()
{
nrf_gpio_cfg_output(LED_1);
nrf_gpio_cfg_output(LED_2);
nrf_gpio_cfg_output(LED_3);
nrf_gpio_cfg_output(LED_4);
nrf_gpio_pin_set(LED_1);
nrf_gpio_pin_set(LED_2);
nrf_gpio_pin_set(LED_3);
nrf_gpio_pin_set(LED_4);
}
/**
* Function for application main entry.
*/
int main(void)
{
init_leds();
init_clock();
uint32_t err_code;
// Button configuration structure.
static app_button_cfg_t p_button[] = { {BUTTON_1, APP_BUTTON_ACTIVE_LOW, NRF_GPIO_PIN_PULLUP, button_handler},
{BUTTON_2, APP_BUTTON_ACTIVE_LOW, NRF_GPIO_PIN_PULLUP, button_handler},
{BUTTON_3, APP_BUTTON_ACTIVE_LOW, NRF_GPIO_PIN_PULLUP, button_handler},
{BUTTON_4, APP_BUTTON_ACTIVE_LOW, NRF_GPIO_PIN_PULLUP, button_handler}};
// Macro for initializing the application timer module.
// It will handle dimensioning and allocation of the memory buffer required by the timer, making sure that the buffer is correctly aligned. It will also connect the timer module to the scheduler (if specified).
APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS, APP_TIMER_OP_QUEUE_SIZE, NULL);
// Macro for initializing the GPIOTE module.
// It will handle dimensioning and allocation of the memory buffer required by the module, making sure that the buffer is correctly aligned.
APP_GPIOTE_INIT(APP_GPIOTE_MAX_USERS);
// Initializing the buttons.
err_code = app_button_init(p_button, sizeof(p_button) / sizeof(p_button[0]), BUTTON_DEBOUNCE_DELAY);
APP_ERROR_CHECK(err_code);
// Enabling the buttons.
err_code = app_button_enable();
APP_ERROR_CHECK(err_code);
while(true)
{
// Do nothing.
}
}
__WEAK void app_error_handler(/*...*/)
__WEAK macro is not defined. Check where __WEAK is declared and make sure the header file is included.
I made simple StringReverse C project in eclipse-cdt (ubuntu 14.0) and made to .so (shared library).
I made test cases for StringReverse C project in eclipse-cdt.
Tests runs successfully.
But, these C project and test cases I wants to run in Socket-Client Programming in eclipse-cdt.
Suppose, I wants to pass test cases in Client side and that test cases find the C function in Server side. How can I make this..?
references for Server-Client Project :
http://www.cs.cf.ac.uk/Dave/C/node28.html#SECTION002800000000000000000
My StringReverse C code :
Include :
#define LENGTH_OF_STRING 20
#include <stdio.h>
#include <string.h>
#include "error.h"
int StringReverse (char *ptrToDestination, char *ptrToSource);
Source :
#include "StringReverse.h"
#include "error.h"
int StringReverse(char *ptrToDestination,char *ptrToSource)
{
int i,j;
if(NULL == (void *)ptrToSource) {
return ERR_NULL_POINTER;
}
if (LENGTH_OF_STRING <= strlen(ptrToSource)) {
return ERR_STRING_LENGTH;
}
if(NULL == (void *)ptrToDestination) {
return ERR_NULL_POINTER;
}
for(i=0; ptrToSource[i]; i++) {
}
for(i=i-1,j=0; i>=0; i--,j++) {
ptrToDestination[j] = ptrToSource[i];
}
ptrToDestination[j] ='\0';
if(strlen(ptrToSource) != strlen(ptrToDestination)) {
return ERR_STRING_LENGTH;
}
return SUCCESS;
}
My test case :
AllTests.cpp :
#include "CommandLineTestRunner.h"
int main(int ac, char** av)
{
int result = RUN_ALL_TESTS(ac, av);
return result;
}
StringReverse_Test.cpp :
extern "C"
{
#include "StringReverse.h"
#include "error.h"
}
#define COUNT_FOR_NULL 1
#include "TestHarness.h"
#include "TestHarness_c.h"
#include <string.h>
int StatusOfStringReverseFunction;
TEST_GROUP(StringReverse)
{
void setup()
{
/**
* This method is used to initialize the test. It is runs before each test.
*
*/
printf("Tests start here...\n");
}
void teardown()
{
/**
* This method is used to finalized the test. It is runs after each test.
*/
printf("Tests end here...\n");
}
};
/**
* \brief
* I require a test which can check the StringReverse function is capable to return the reverse a string,
* if I assigned string to pointer.
*
* \details
* I require two character pointers for the test.
* char *ptrToSource contains input as string.
* char *ptrToDestination contains the result of StringReverse function.
* I extend StringReverse function to reverse the string assigned by pointer.
* I check the StringReverse function is capable to return the reverse a string or not, using LONGS_EQUAL macro.
*/
TEST(StringReverse, tst_StringReverse_PointerToString)
{
char *ptrToSource = "abcdefghijkl";
char *ptrToDestination = NULL;
CHECK(NULL != ptrToSource);
ptrToDestination = (char *) malloc((strlen(ptrToSource)+COUNT_FOR_NULL)*sizeof(char));
CHECK(NULL != ptrToDestination);
StatusOfStringReverseFunction = StringReverse(ptrToDestination, ptrToSource);
CHECK(strlen(ptrToDestination) == strlen(ptrToSource));
LONGS_EQUAL(SUCCESS, StatusOfStringReverseFunction);
free ((void *)ptrToDestination);
}
/**
* \brief
* I require a test by which can I check that function StringReverse is capable to make the null string is reverse or not.
*
* \details
* I require two character arrays.
* char source[LENGTH_OF_STRING] contains input as a null string.
* char destination[LENGTH_OF_STRING] contains the result of StringReverse function.
* I extend StringReverse function to check the null string is reverse or not.
* I check the StringReverse function is capable to return null string or not, using macro LONGS_EQUAL.
*/
TEST(StringReverse, tst_StringReverse_Null)
{
char source[LENGTH_OF_STRING] = "";
char destination[LENGTH_OF_STRING];
StatusOfStringReverseFunction = StringReverse (destination, source);
LONGS_EQUAL(SUCCESS, StatusOfStringReverseFunction);
}
What is the solution ?