I need to unload a DLL that was loaded by ::ffidl::symbol in a ::ffidl::callout statement in Tcl.
I could use ::twapi::FreeLibrary, but it requires the DLL's load address, which ffidl doesn't seem to expose.
The problem with unloading a library (any library) is that there may be dangling pointers left behind. This leaves a whole series of little landmines in your code. So be aware!
To hack it, the address of the library can be obtained by using ffidl to call Tcl_LoadFile, which is (essentially) the Tcl API that ffidl uses to load the library in the first place, and Tcl_FSUnloadFile, which is a wrapper round the unload functionality you want.
# I'm not sure that I've got these type signatures right!
ffidl::callout Tcl_LoadFile \
{pointer-byte pointer-utf8 pointer-byte int pointer-byte pointer-int} int \
[ffidl::symbol tcl.dll Tcl_LoadFile]
ffidl::callout Tcl_FSUnloadFile \
{pointer-byte int} int \
[ffidl::symbol tcl.dll Tcl_FSUnloadFile]
set handleVar [binary format I 0]
Tcl_LoadFile 0 "theDll.dll" 0 0 0 handleVar
Tcl_FSUnloadFile 0 $handleVar
(Warning! I've not used ffidl before and this is untested code! I'd actually use Critcl instead for this, as I think it is easier to write a little glue code in embedded-C.)
Related
I am writing the code for expression evaluator using lex and yacc which can have following operations:
/ , * , + , - , pow(a,b) , sqrt(a) , log(a)
also there can be brackets in the expression.
Input expression is in the file "calculator.input"
I have to compare the time of my code with bc, I am facing following problems:
1) bc doesn't accept pow(a,b) and log(a) it instead accepts a^b and l(a) .
How do I change it?
2) How do I use the bc from the main funtion in the yacc program ? or that can't be done?
I think it would be easier to change your code than to change bc, but if you want to try, you can find pointers to bc's source bundles on the GNU project page and in the FreeBSD source mirror. Of course, the end result would not strictly speaking be bc any more, so I don't know if it would still count, for the purposes of your assignment.
I don't know what the specifications are for the pow function you are supposed to implement, but note that bc's ^ operator only allows integer exponents, so it might not work on all your test cases (unless, of course, all your test cases have integer exponents.) You could compute a^b with e(l(a)*b), but it won't be as accurate for integer exponents:
e(l(10)*100)
99999999999999999920085453156357924020916787698393558126052191252537\
96016108317256511712576426623511.11829711443225035170
10^100
10000000000000000000000000000000000000000000000000000000000000000000\
000000000000000000000000000000000
You might want to consult with your tutor, professor, or teaching assistant.
If you don't want to (or are not allowed to) generate the bc equivalent test cases by hand, you might be able to automate the process with sed (if the exponential sub-expressions are not complicated), or by adapting your calculator to output the expression in bc's syntax. The latter would be a fairly easy project, and you'd probably learn something by implementing it.
If you are using a Unix-like system, you can easily run any command-line utility from a C program. (Indeed, you can do that on non-Unix-like systems, too, but the library functions will differ.) If you don't need to pass data to bc through its stdin, you can use the popen(3) library function, which is certainly the easiest solution.
Otherwise, you will have to set up a pair of pipe(2)s (one for writing to bc's stdin and the other for reading from its stdout), fork(2) a child process, and use one of the exec* function calls, probably execlp(3) or execvp(3), to run bc in the child. (Watch out for pipe deadlock while you are writing to and reading from the child.) Once the child process finishes (which you'll notice because you'll get an EOF on the pipe you're using to read from its stdout, you should use wait(3) or waitpid(3) to get its status code.
If all that seems too complicated, you could use the much simpler solution of running both your program and bc from your shell. (You can use the time shell built-in on Unix-like shells to get a measure of execution time, although it will not be microsecond resolution which might be necessary for such a simple program.)
I am using Xilinx ISE 10.1 to run some verilog code. In the code I want to write the register values of 3 registers in a file, cipher.txt. The following is the code snippet:
if (clk_count==528) begin
f1 = $fopen("cipher.txt", "w");
$fwrite(f1, "clk: %d", clk_count[11:0]);
$fwrite(f1, "plain: %h", plain[31:0]);
$fwrite(f1, "cipher: %h", cipher[31:0]);
$fclose(f1);
end
At the end of execution, the contents of cipher.txt is found as:
clk: %dplain: %hcipher: %h
There is no other error encountered, but a warning comes up corresponding to the 3 fwrite's:
Parameter 3 is not constant in call of system task $fwrite.
Parameter 3 is not constant in call of system task $fwrite.
Parameter 3 is not constant in call of system task $fwrite.
The values of the registers clk_count and cipher change on every clock cycle (value of register plain remains constant throughout), and the values are written to cipher.txt when clk_count equals 528 (indicated by the if statement)
Can anybody provide some insight and/or help me get past this hurdle?
Thanks.
It appears that ISE expects the arguments to $fwrite to be constant. The warnings are referring to clk_count[11:0], plain[31:0], and cipher[31:0], which are not constant. By definition they are changing each cycle so they are not known at compile time. This also explains why they are not printing and you are seeing %d and %h in the output.
There is nothing to my knowledge in the Verilog spec that requires the arguments to $fwrite be constant. The same code works as expected with Cadence Incisive. My guess is that it's a limitation of ISE, so you may want to check with Xilinx.
Possible work-arounds:
1) Use $swrite to create a string with the proper formatting. Then write the string to the file.
2) Try using an intermediate variable in the calls to $fwrite. Maybe the part-selects are throwing it off. e.g.
integer foo;
foo = clk_count[11:0];
$fwrite(... , foo , ...);
Either of those might work, or not.
Out of curiosity, if you remove the part-selects, and try to print clk_count without the [11:0] , do you get the same warnings?
I'm currently writing a script that processes batches of quicktimes, and its my first time using pyobjc (I have only written one other really simple script in actual objective-c). I need to be able to determine the four character OSType of the codec of the quicktimes so that I can properly use the same codec for images using addImage_forDuration_withAttributes_()
Because pyobjc only has access to the obj-c frameworks, I can't access any of the C functions from it. I am able to get the string format UTType of the codec:
from objc import YES, NO, nil
from Cocoa import *
from QTKit import *
movieAttribs = {
QTMovieOpenAsyncOKAttribute: NSNumber.numberWithBool_(NO),
QTMovieEditableAttribute: NSNumber.numberWithBool_(YES),
QTMovieFileNameAttribute: "quicktime.mov"
}
clip, err = QTMovie.movieWithAttributes_error_(movieAttribs, None)
track = clip.tracks()[0]
print track.format()
# u'Avid DNxHD Codec'
At this point I need to get the OSType, which for this codec would be 'AVdn'
I'm assuming I want something like this: https://developer.apple.com/library/mac/#documentation/MobileCoreServices/Reference/UTTypeRef/Reference/reference.html But I don't have access to it in pyobjc
My last resort is to shell out to qt_thing with something like this:
qt_thing --type=imco | grep "AVID DNxHD Codec" | awk -F: '{print $2}'
# Result: AVdn
But this is slower and I would rather do it all in code. I must be missing something that is available to me in the Cocoa/QTKit side of things. Anyone with any experience?
There is another SO question that again references using the C api to resolve the codec: Find out the Codec for a Quicktime Movie, but I can't obviously do that directly form pyobjc as far as I know.
While I waited for someone to answer, and kept digging, even into the Carbon module... I found that there are quite a number of methods wrapped into pyobjc objects that are not really documented in the docs or probably even present in the native QTKit objc. I figure this is to offset the lack of access to the Quicktime C-api layer.
First my search turned up this QTKit class: QTFormatDescription
But there was no clear way how to create one of these. Apparently I wasn't the only one confused as to how to retrive one
When I started searching the actual members of QTMovie, QTTrack, and QTMedia objects, looking for possibly a way to retrieve a QTFormatDescription object, I stumbled across a method call: QTTrack.mediaSubType
>>> movie = QTMovie.alloc().initWithFile_error_("/path/to/quicktime.mov", None)
>>> track = movie.tracks()[1]
>>> track.mediaSubType()
u'AVdn'
I guess they do wrap up a lot of convenience methods into the pyobjc instances so that you can retrieve this kind of information without the C-api. Its just a shame that its so undocumented.
For anyone looking for random functionality like this, all I can recommend is doing something like this to find any added non-arg methods that might be available to you:
>>> print '\n'.join([attrib for attrib in dir(QTTrack) if not '_' in attrib])
....
mediaName
mediaRetained
mediaSubType
mediaType
mediaTypeInMedia
...
pyobjc does contain access to UTType it's under LaunchServices.
from LaunchServices import *
UTCreateStringForOSType()
UTGetOSTypeFromString()
Stupid question that I'm sure is some bit of syntax that's not right. How do I get dlsym to work with a function that returns a value? I'm getting the error 'invalid conversion of void* to LSError (*)()' in the following code - trying to get the compile the linux lightscribe sample program hoping that I can link it against the OSX dylib (why the hell won't HP release an actual Cocoa SDK? LS has only been around for what? 6 or 7 years now?):
void* LSHandle = dlopen("liblightscribe.1.dylib", RTLD_LOCAL|RTLD_LAZY);
if (LSHandle) {
LSError (*LS_DiscPrinter_ReleaseExclusiveUse)() = dlsym(LSHandle, "LS_DiscPrinter_ReleaseExclusiveUse");
..
lsError = LS_DiscPrinter_ReleaseExclusiveUse( pDiscPrinter);
The C standard does not actually define behaviour for converting to and from function pointers. Explanations vary as to why; the most common being that not all architectures implement function pointers as simple pointers to data. On some architectures, functions may reside in an entirely different segment of memory that is unaddressable using a pointer to void.
The “recommended” way to use dlsym is:
LSError (*LS_DiscPrinter_ReleaseExclusiveUse)(LS_DiscPrinterHandle);
*(void **)&LS_DiscPrinter_ReleaseExclusiveUse = dlsym("LS_DiscPrinter_ReleaseExclusiveUse");
Read the rationale and example on the POSIX page for dlsym for more information.
Ok I finally found the problem. It was inside the C function(CarbonTuner2) not the objC method. I was creating inside the function an array of the same size as the file size so if the filesize was big it created a really big array and my guess is that when I called another function from there, the local variables were put on the stack which created the EXC_BAD_ACCESS. What I did then is instead of using a variable to declare to size of the array I put the number directly. Then the code didnt even compile. it knew. The error wassomething like: Array size too big. I guess working 20+hours in a row isnt good XD But I am definitly gonna look into tools other than step by step debuggin to figure these ones out. Thanks for your help. Here is the code. If you divide gFileByteCount by 2 you dont get the error anymore:
// ConverterController.h
# import <Cocoa/Cocoa.h>
# import "Converter.h"
#interface ConverterController : NSObject {
UInt64 gFileByteCount ;
}
-(IBAction)ProcessFile:(id)sender;
void CarbonTuner2(long numSampsToProcess, long fftFrameSize, long osamp);
#end
// ConverterController.m
# include "ConverterController.h"
#implementation ConverterController
-(IBAction)ProcessFile:(id)sender{
UInt32 packets = gTotalPacketCount;//alloc a buffer of memory to hold the data read from disk.
gFileByteCount=250000;
long LENGTH=(long)gFileByteCount;
CarbonTuner2(LENGTH,(long)8192/2, (long)4*2);
}
#end
void CarbonTuner2(long numSampsToProcess, long fftFrameSize, long osamp)
{
long numFrames = numSampsToProcess / fftFrameSize * osamp;
float g2DFFTworksp[numFrames+2][2 * fftFrameSize];
double hello=sin(2.345);
}
Your crash has nothing to do with incompatibilities between C and ObjC.
And as previous posters said, you don't need to include math.h.
Run your code under gdb, and see where the crash happens by using backtrace.
Are you sure you're not sending bad arguments to the math functions?
E.g. this causes BAD_ACCESS:
double t = cos(*(double *)NULL);
Objective C is built directly on C, and the C underpinnings can and do work.
For an example of using math.h and parts of standard library from within an Objective C module, see:
http://en.wikibooks.org/wiki/Objective-C_Programming/syntax
There are other examples around.
Some care is needed around passing the variables around; use the C variables for the C and standard library calls; don't mix the C data types and Objective C data types incautiously. You'll usually want a conversion here.
If that is not the case, then please consider posting the code involved, and the error(s) you are receiving.
And with all respect due to Mr Hellman's response, I've hit errors when I don't have the header files included; I prefer to include the headers. But then, I tend to dial the compiler diagnostics up a couple of notches, too.
For what it's worth, I don't include math.h in my Cocoa app but have no problem using math functions (in C).
For example, I use atan() and don't get compiler errors, or run time errors.
Can you try this without including math.h at all?
First, you should add your code to your question, rather than posting it as an answer, so people can see what you're asking about. Second, you've got all sorts of weird problems with your memory management here - gFileByteCount is used to size a bunch of buffers, but it's set to zero, and doesn't appear to get re-set anywhere.
err = AudioFileReadPackets (fileID,
false, &bytesReturned, NULL,0,
&packets,(Byte *)rawAudio);
So, at this point, you pass a zero-sized buffer to AudioFileReadPackets, which prompty overruns the heap, corrupting the value of who knows what other variables...
fRawAudio =
malloc(gFileByteCount/(BITS/8)*sizeof(fRawAudio));
Here's another, minor error - you want sizeof(*fRawAudio) here, since you're trying to allocate an array of floats, not an array of float pointers. Fortunately, those entities are the same size, so it doesn't matter.
You should probably start with some example code that you know works (SpeakHere?), and modify it. I suspect there are other similar problems in the code yoou posted, but I don't have time to find them right now. At least get the rawAudio buffer appropriately-sized and use the values returned from AudioFileReadPackets appropriately.