I found this code on the internet:
#include <string.h>
#include <malloc.h>
#include <espeak/speak_lib.h>
espeak_POSITION_TYPE position_type;
espeak_AUDIO_OUTPUT output;
char *path=NULL;
int Buflength = 1000, Options=0;
void* user_data;
t_espeak_callback *SynthCallback;
espeak_PARAMETER Parm;
char Voice[] = {"English"};
char text[30] = {"this is a english test"};
unsigned int Size,position=0, end_position=0, flags=espeakCHARS_AUTO, *unique_identifier;
int main(int argc, char* argv[] )
{
output = AUDIO_OUTPUT_PLAYBACK;
int I, Run = 1, L;
espeak_Initialize(output, Buflength, path, Options );
espeak_SetVoiceByName(Voice);
const char *langNativeString = "en"; //Default to US English
espeak_VOICE voice;
memset(&voice, 0, sizeof(espeak_VOICE)); // Zero out the voice first
voice.languages = langNativeString;
voice.name = "US";
voice.variant = 2;
voice.gender = 1;
espeak_SetVoiceByProperties(&voice);
Size = strlen(text)+1;
espeak_Synth( text, Size, position, position_type, end_position, flags,
unique_identifier, user_data );
espeak_Synchronize( );
return 0;
}
I only want the espeak reads my strings in my program, and the above code can do it, but I want to know, are all of this code necessary for that purpose? (I mean is it possible to simplifying it?)
***Also I like to know are there a way to using espeak as a system function? I mean system("espeak "something" "); ?
The usage of eSpeak itself seems pretty minimal - you need to read the documentation for that. There are some minor C coding simplifications possible, but perhaps hardly worth the effort:
The memset() is unnecessary. The structure can be initialised to zero thus:
espeak_VOICE voice = {0} ;
If you declare text thus:
char text[] = "this is a English test";
Then you can avoid using strlen() and replace Size with sizeof(text).
The variables I, Run and L are unused and can be removed.
To be able to pass the text as a string on the command line, and thus be able to issue system( "espeak \"Say Something\"") ; for example, you simply need to pass argv[1] to espeak_Synth() instead of text (but you will need to reinstate the strlen() call to get the size.
Related
I tried to write a function similar to sscanf that forwards the input string pointer, so it could be used like scanf to scan multiple strings one after the other. when I tried to use the function
there was an exception so I ran it in debug and it is unable to read the input Strings value.
int scanStrAndMove(char **readString, char* formatString, char * writeString){
int forwardBy = 0;
while(isspace(*readString[forwardBy])){
forwardBy++;
}
int retVal = sscanf(*readString,formatString,writeString);
forwardBy += strlen(writeString) + strlen(formatString) - 2;
if(retVal > 0) *readString += forwardBy;
return retVal;
}
a screenshot of the problem
the calling of the function(line is of type char*)
edit: I tried to replace readString with another char to and it didn't solve the problem, thanks for all the answers.
edit: I saw the comments and tried to make a minimal reproducible example, try to run this with the function above:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char inputStr[10] = " cde fg";
char outputSrt[10];
scanStrAndMove(&inputStr,"%s",outputSrt);
printf("%s",outputSrt);
scanStrAndMove(&inputStr,"%s",outputSrt);
printf("%s",outputSrt)
}
because of my limited knowledge in C and SWIG i couldn't manage to adopt any public example for converting c-pointer chars to tcl strings ....
I always get stuck at the problem that my tcl variable just doesn't get dereferenced
like this :
tcl_str = _30e84c05ef550000_p_stringout2
string_pointer.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include "string_pointer.h"
stringout2 Itla_Get_Model_Version (int laser, char * mv_string)
{
stringout2 * pointer2;
char *mod_ver ="PPCL600";
pointer2 = malloc( sizeof(stringout2) );
pointer2-> modelvers= *mod_ver;
printf ( "Itla_Get_Model_Version : read %s \n", mod_ver );
return *pointer2 ;
}
string_pointer.h
#include <sys/types.h>
#include <sys/resource.h>
typedef struct {
char * modelvers;
} stringout2;
stringout2 Itla_Get_Model_Version (int laser, char * mv_string) ;
string_pointer.swig
/* File : string_pointer.swig */
%module string_pointer
%{
#include "string_pointer.h"
%}
%include "typemaps.i"
%include "cpointer.i"
%include "cstring.i"
%typemap(argout) char* (char tmp) %{
$1 = &tmp;
%}
stringout2 Itla_Get_Model_Version (int laser, char *OUTPUT) ;
%include "string_pointer.h"
test.tcl
load ./string_pointer.so
proc test { laser } {
scan [Itla_Get_Model_Version $laser ] %s a
puts "$a "
return $a
}
set name [test 1 ]
puts "Itla_Get_Model_Version= $name"
when executing the tcl-script you get :
Itla_Get_Model_Version : read PPCL600
_f0a759f8d9550000_p_stringout2
Itla_Get_Model_Version= _f0a759f8d9550000_p_stringout2
so i finally need to dereference the Pointer to its value ...
But i don't know how to succeed.....
The C-function is given and can't be modified !
Anybody out there, knowing how to do it ?
If your strings are basically ASCII or UTF-8, all you need to do is to tell SWIG that your function has allocated the string it is returning. For details see, the SWIG docs on C strings.
yourcode.c
char *Itla_Get_Model_Version (int laser, char * mv_string) {
// I assume this is a proxy for something more complicated...
const char *mod_ver ="PPCL600";
size_t len = strlen(mod_ver) + 1;
char *output = malloc(len);
memcpy(output, mod_ver, len);
printf ( "Itla_Get_Model_Version : read %s \n", mod_ver );
return output;
}
yourcode.h
char *Itla_Get_Model_Version(int laser, char * mv_string);
yourcode.swig
/* Tell SWIG that this function returns something to be freed */
%newobject Itla_Get_Model_Version
/* And now we can use the standard C header */
%include "yourcode.h"
If the above simple solution doesn't work…
Things get a lot more complicated if you are using a different encoding for your strings or if you wrap them inside a structure (as you did in your question). That's when you need a typemap, particularly ones of the Tcl variety. Correctly writing a typemap depends on understanding the semantics of the values that you are producing and/or consuming and the semantics of the language that you're using. Assuming you want the wrapping, here's a very simple output typemap that might work:
%typemap(out) stringout2* {
Tcl_SetObjResult(interp, Tcl_NewStringObj($1->modelvers, -1));
free($1);
}
Your function also needs to be modified to return a stringout2* by doing return pointer2;, and not a stringout2 since otherwise you will be leaking memory on every call. You can return a stringout2, but if you are doing that then you should not allocate it with malloc, but rather keep it as a structure directly in a local variable.
In that case, the typemap you'd use is:
%typemap(out) stringout2 {
Tcl_SetObjResult(interp, Tcl_NewStringObj($1.modelvers, -1));
}
(Note the different type, different access to the field, and lack of free.)
And your structure should be declared as containing a const char * if it really is that.
If you have strings in a different encoding (and it isn't ISO 8859-1, for which you can cheat and use a binary string using Tcl_NewByteArrayObj; that's also what you want for slabbing a chunk of binary data over) then you'll need to write a typemap using Tcl_ExternalToUtfDString, and the amount of boilerplate code goes up. Tcl insists that its internal strings are in (almost) UTF-8, and ASCII is OK too as that's a strict subset; everything else must be converted.
Ask another question if that's what you need. You probably are either dealing with ASCII or binary data, so I'll leave (quite a bit more complex!) encoding conversion alone until requested.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 7 years ago.
Improve this question
Got this great C program I'd like to embed into an iOs app.
One passes command line arguments to it and the results are printed to stdout via printf and fputs - like with all the good old unix programs.
Now I'd like to just edit main and the print functions to use my own printf function which collects all the output that normally goes to stdout and return it at the end.
I implemented a solution by using a line buffer to collect all the printfs until the newline.
And a dynamic char array whereto I copy when an output line is finished.
The charm of this solution is - it's kind of tcl'ish: just throw everything into a text line and if its complete store it. Now do that as long as necessary and return the whole bunch at the end ...
And here the question:
It works - but as I am fairly new in "real" programming - i.e. C and Apples "brandnew" Swift - am not sure wheter this is a good solution. Is it? And if not - what would you suggest? Thank you very much!
Here follows the C code:
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
// outLineBuffer collects one output line by several calls to tprntf
#define initialSizeOfReturnBuffer 10 // reduced for testing (would be 16*1024)
#define incrSizeOfReturnBuffer 5 // reduced for testing (would be 1024*1024)
#define outLineBufferMaxSize 4095
char outLineBuffer[sizeof(char)*outLineBufferMaxSize] = "";
char *tReturnString;
size_t sizeOfReturnBuffer, curPosOutBuffer = 0, lenOutLine = 0;
With the replacement tprntf for all the original printf and fputs:
// replace printf with this to collect the parts of one output line.
static int tprntf(const char *format, ...)
{
const size_t maxLen = sizeof(char)*outLineBufferMaxSize;
va_list arg;
int done;
va_start (arg, format);
done = vsnprintf (&outLineBuffer[lenOutLine], maxLen-lenOutLine, format, arg);
va_end (arg);
lenOutLine = strlen(outLineBuffer);
return done;
}
And the function when we complete one output line (everywhere \n is printed):
// Output line is now complete: copy to return buffer and reset line buffer.
static void tprntNewLine()
{
size_t newSize;
long remainingLenOutBuffer;
char *newOutBuffer;
remainingLenOutBuffer = sizeOfReturnBuffer-curPosOutBuffer-1;
lenOutLine = strlen(outLineBuffer)+1; // + newline character (\n)
remainingLenOutBuffer -= lenOutLine;
if (remainingLenOutBuffer < 0) {
newSize = sizeOfReturnBuffer + sizeof(char)*incrSizeOfReturnBuffer;
if ((newOutBuffer = realloc(tReturnString, newSize)) != 0) {
tReturnString = newOutBuffer;
sizeOfReturnBuffer = newSize;
} else {
lenOutLine += remainingLenOutBuffer; //just write part that is still available
remainingLenOutBuffer = 0;
}
}
snprintf(&tReturnString[curPosOutBuffer], lenOutLine+1, "%s\n", outLineBuffer);
curPosOutBuffer += lenOutLine;
outLineBuffer[0] = 0;
lenOutLine = 0;
}
And a little main to test it (without swift - e.g. plain gcc):
int main(int argc, char *argv[])
{
int i;
sizeOfReturnBuffer = initialSizeOfReturnBuffer*sizeof(char);
if ((tReturnString = malloc(sizeOfReturnBuffer)) == 0) {
return 1; // "Sorry we are out of memory. Please close other apps and try again!";
}
tReturnString[0] = 0;
for (i = 1; i < argc; i++) {
tprntf("%s ", argv[i]);
}
tprntNewLine();
tprntf("%s", "ABC\t");
tprntf("%d", 12);
tprntNewLine(); // enough space for that ;-)
tprntf("%s", "DEF\t");
tprntf("%d", 34);
tprntNewLine(); // realloc necessary ...
tprntf("%s", "GHI\t");
tprntf("%d", 56);
tprntNewLine(); // again realloc for testing purposes ...
printf("tReturnString at the end:\n>%s<\n", tReturnString); // contains trailing newline
return 0;
}
The call from swift will the be as follows (using CStringArray.swift)
let myArgs = CStringArray(["computeIt", "par1", "par2"])
let returnString = mymain(myArgs.numberOfElements, &myArgs.pointers[0])
if let itReturns = String.fromCString(returnString) {
print(itReturns)
}
freeMemory()
I am sure that tcl has many optimizations and I suggest you also optimize the code; then your approach can be viable.
Check your frequent use of strlen, which every time goes through all the (many) characters to count the length - use information about its length, for example maintain a char *outLineBufPtr. Also use strcat to append \n to outLineBuffer instead of using the expensive vsnprintf function, or just copy the char manually, as *outLineBufPtr++ ='\n'; .
To implement a higher-level concept such as yours, you must start thinking in machine cycles so the higher-level concept does not become "expensive".
I've got some code which generates an array of strings of different file names and then
passes them into a function to write some data to them. It adds a incrementing number to the starting filename which is supplied from an input argument.
The problem is that it works fine running from source in Visual Studio 2012 but when I compile it and run it as an .exe the program crashes.
The .exe doesn't appear to be passing the array of strings properly which is causing an error when it attempts to use the string
for opening a file etc.
Here is the isolated bit of code
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <string.h>
#include <stdint.h>
#include <Windows.h>
void processing_function(int num_output, char **outnames)
{
/* in Visual Studio this works fine and prints all
the names correctly. Running from .exe will crash */
for(int idx = 0; idx <num_output;idx++)
{
printf("outnames[%d] is %s\n",idx,outnames[idx]);
}
}
int main(int argc, char *argv[])
{
/*nframes comes from another function, outname comes from input arguement */
int num_output = ceil(((double)*nframes / 1100));
int outname_len = strlen(outname)+1;
char *out_right;
out_right = (char*) malloc(sizeof(char)*outname_len);
/*Split string to append numbers before file extension */
strcpy(out_right,outname);
strrev(out_right);
strtok(out_right,".");
strcat(out_right,".");
strrev(out_right);
int out_right_len = strlen(out_right);
strtok(outname,".");
strcat(outname,"-");
int out_origlen = strlen(outname);
int num_len = 1;
char **outnames;
char *num;
char *outname_tmp;
outnames = (char**) malloc(sizeof(char)*(num_output));
int out_len;
double dbl_idx;
int *numfs = (int*)malloc(sizeof(int)*num_output);
for(int idx = 1;idx <num_output+1;idx++)
{
/*convert output number to string and stitch complete name back together and place into array */
num_len = ceil(log10((double)idx+0.1));
num = (char*) malloc(sizeof(char)*(num_len+1));
outname_tmp = (char*) malloc(sizeof(char)*(out_origlen+num_len+out_right_len+1));
strcpy(outname_tmp,outname);
sprintf(num,"%d",idx);
strcat(outname_tmp,num);
free(num);
strcat(outname_tmp,out_right);
outnames[idx-1] = (char*) malloc(sizeof(char)*(out_origlen+num_len+out_right_len+1));
strcpy(outnames[idx-1],outname_tmp);
free(outname_tmp);
printf("%s\n",outnames[idx-1]);
}
free(out_right);
processing_function(num_ouput, outnames)
return(0);
}
EDIT: Changed num_input to num_output as they do have the same value.
Running from .exe will sometimes start printing some of the names and then crash, opening the
debugger gives an error within output.c, with an access reading violation. I tried putting this code at
the top of the processing_function but that gave further problems downstream (heap corruption), which makes me think that the
code is messing up the memory but I can't see whats wrong with it, nor why it would work in VS but not as a .exe.
I could try and dodge the issue by generating the next output name on the fly every time it requires one but I'd really rather know why this isn't working.
Any help would be greatly appreciated.
I am going to take a shot and say, you passed num_input to processing_function() with outnames, outnames was allocated with num_output for size, but num_input and num_output have different values at runtime. So that lets processing_function() access out of bounds.
Im working on a server in C that dynamically generating Lua commands on the fly and send them by socket to the clients. Right now the server is using plain text, but I would like the server to pre-compile the script before sending it to the clients.
I check luac.c but couldn't find how to be able to do something like this:
char lua_commands[ 1024 ] = { "a = 123; b = 456; c = a + b;" };
int socket
unsigned int send_buffer_size
unsigned char *send_buffer
/* Compile lua_commands and store the binary script into send_buffer without
having to write first the .out on disk then read it again in order store the content
into send_buffer */
send( socket, send_buffer, send_buffer_size, 0 );
Anybody can help me to achieve this?
[ Update ]
Ok, I think I figure it out:
#include "lua.h"
#include "lauxlib.h"
#include "ldo.h"
#include "lfunc.h"
#include "lmem.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lstring.h"
#include "lundump.h"
#define toproto(L,i) (clvalue(L->top+(i))->l.p)
static int writer( lua_State *L, const void *p, size_t size, void *u ){
unsigned int i = 0;
unsigned char *d = ( unsigned char * )p;
// Print all the bytes on the console.
while( i != size ) {
printf("%d ", d[ i ] );
++i;
}
return 0;
}
void compile( lua_State *L, char *command ){
const Proto* f;
if (luaL_loadstring( L, command ) !=0 ) {
printf( "%s\n", lua_tostring( L, -1 ) );
}
f = toproto( L,-1 );
lua_lock( L );
luaU_dump( L, f, writer, NULL, 1 );
lua_unlock( L );
}
int main (int argc, const char * argv[]) {
lua_State *L = lua_open();
compile( L, "a = 123; b = 456; c = a + b; print( c );" );
lua_close( L );
return 0;
}
However that leads me to another question, do I have to close and reopen (lua_open, lua_close) the Lua state every time I'm calling my compile() function with other Lua commands or the output will only be the result of the latest luaL_loadstring?
Im not sure but look to me from the toproto macro definition that the top most stack will be returned am I correct?
You should use lua_dump() instead of internal toproto() + luaU_dump() functions. As an added bonus, this way your code will support LuaJIT 2.
It is not necessary to recreate the state each time you get the dump.
BUT. I would avoid executing Lua bytecode that came from the untrusted source (and server often is untrusted to the client). It is not safe, and may lead to severe security issues. (No such problems with source code — but you still have to sandbox it, of course.)
In general, always make sure that you check that the code you load from untrusted source is not bytecode (it is, if first byte is 27 decimal). Always execute such code in a sandbox.
If all that you need is to pass data in Lua-friendly way, pick some proper data serialization library instead. Aside of sandboxing and portability problems, loadstring() is rather slow.
For example, we're using using my luatexts library for similar purposes (make sure to pore through this list for alternatives). Luatexts supports tuples, which plays nicely with function calls. For example (in pseudocode):
Server:
my_send(luatexts.lua.save("myMethod", { param = true }, 42))
Client:
local actions = { }
function actions.myMethod(params, number)
print(params.param, number) --> true, 42
end
local function handle_action(ok, name, ...)
assert(ok, name) -- name would contain error message if not OK
local handler = assert(actions[name], "unknown action")
return handler(...)
end
local str = my_receive()
handle_action(luatexts.load(str))
Open a ticket if you want luatexts.save or streaming support implemented in C.