Timers...
I have a call to a dll function which creates an output.txt file.
I need to use that file afterwards, but have no way to know how long it is going to take to create the file. The function has no return.
Any ideas?
Timers...
I have a call to a dll function which creates an output.txt file.
I need to use that file afterwards, but have no way to know how long it is going to take to create the file. The function has no return.
Any ideas?
The function has to return at some point, right? Is the call being done in a thread? You could use a mutex on the file if you have access to the function in the DLL.
You'll have to give more detail if you want a good answer.
If you understand what you're doing, you're not learning anything.
The dll function is being called, takes an input.xxx and creates an output.xxx which I need send back around for each ext.
I guess I have two questions:Code:void createOutputFile() { int errorCode; int index = 0; char oldName[BUFFER_SIZE]; char newName[BUFFER_SIZE]; char* ext[] = {".a", ".b", ".c"}; int arraySize = 3; // The first text file. strcpy(oldName, "input"); strcat(oldName, ".txt"); for (index = 0; index < arraySize; index++) { strcpy(newName, "input"); strcat(newName, ext[index]); // This should be input.a input.b etc.. result = renameFile(oldName, newName); if (result != 0) {..... Did not rename, handle error} // Function from dll which looks for the input.xxx file in the current dir, // manipulates it and creates an output.xxx" file. createOutputFile(); // Gets the output.xxx file to be copied as the next source. strcpy(sourceFile, "output"); strcat(sourceFile, ext[index]); // This will be output.a output.b etc... } }
One is, I cannot iterate through the loop until the createOutputFile is created. Not sure how I manage that?
Two is, if I want to reuse the oldName and newName, in a loop through the list of file names. I know what I'm doing is wrong, just wrote it to get the idea across, but not sure how to reuse the char array when the file names may vary in length.
Are you saying that the createOutputFile() functions returns before the conversion is complete? That would imply that it is launching some external program, or creating a thread. If that's the case, there is no solution to this problem. You have to have a way of knowing when the processing is done. Unless the DLL gives you a way of determining this, you're out of luck.
Won't that code just recursively call itself? Why is this function called createOutputFile() and calling a function of the same name in the DLL?
Sorry, my bad for typing the wrong name ...
The dll function call is not the same as the function call.
Yes, the dll function call does not return with a value to indicate that it has completed. It's writing a small file, which is quick, but does not return nonetheless.
It grabs the input.xxx file and creates an output.xxx file.
Any help on how to reuse an array to store the new/oldNames?
I'm crashing out ... Instead of pieces, here's the chunk of it. Please help....
I have a function that I call from Java ... It initializes the DLL, returns if that fails, otherwise calls the createOutputFile() and returns.
Code:......... jboolean someBigLongJNIMethodName() { int errorCode = initializeMyDLL(); if (errorCode) { printf("Unable to load DLL"); return FALSE; } createOutputFile(); printf("Returned from createOutputFile()"); if (hLib) { FreeLibrary((HMODULE)hLib); } return TRUE; }
The following method is used to take the input.txt file and modify it through a series of calls to the DLL.
The extensions correspond to the DLL function calls. If the extension is a, it calls dllFuncationA() and so forth.
The first source would be input.txt -- which gets renamed to input.a and the dllFunctionA() gets called -- if the source file existed and was successfully renamed to input.a
The DLL function generates an output file as output.xxx. So the dllFunctionA generates an output.a file.
The output.a file then gets renamed to input.b and the dllFunctionB is called.
Code:void createOutputFile() { int errorCode; int index; char* source = NULL; char* destination = NULL; char* ext[] = {"a", "b", "c"}; int arraySize = 3; char INPUT[] = "input."; char OUTPUT[] = "output."; // The first text file. source = malloc(strlen("input.txt") + 1); if (!source) return; strcpy(source, "input.txt"); if (!exists(source)) { if (source) { free(source); source = NULL; } return; } for (index = 0; index < arraySize; index++) { if ((!ext[index]) || (strlen(ext[index]) == 0)) return; if (destination) { free(destination); destination = NULL; } destination = malloc(strlen(INPUT) + strlen(ext[index]) + 1); strcpy(destination, INPUT); strcat(destination, ext[index]); if (!exists(source)) { if (source) { free(source); source = NULL; } if (destination) { free(destination); destination= NULL; } return; } rename(source, destination); if (!exists(destination)) { if (source) { free(source); source = NULL; } if (destination) { free(destination); destination= NULL; } return; } if (strcmp(ext[index], "a") == 0) { dllFuncationA(); } else if (strcmp(ext[index], "b") == 0) { dllFuncationB(); } else if (strcmp(ext[index], "c") == 0) { dllFuncationC(); } if (source) { free(source); source = NULL; } source = malloc(strlen(OUTPUT) + strlen(ext[index]) + 1); strcpy(source, OUTPUT); strcat(source, ext[index]); } if (exists(source)) { rename(source, "final.txt"); if (exists("final.txt")) printf("COMPLETE"); else printf("FAILED"); } if (source) { free(source); source = NULL; } if (destination) { free(destination); destination= NULL; } printf("Test: Last line of code in getOutputFile()"); }
This all seems to work now, except it crashes out when I return from the getOutputFile() method.
The last print statement is displayed on the console and then I get an ACCESS_EXCEPTION_VIOLATION blah, blah, blah error.
The print statement after the getOutputFile() is never reached.
I like it has to do with the dllFunctionXXX calls.....
I pulled out this section of code, and made it a function on it's own, passing in the ext[index] as the argument. When I did that, the program crashes on the return back from that method instead.
I've managed to relocate the crash , but does me no good. The DLL functions are working and an output.xxx file is produced. Not sure what is going on.
Code:void callDllMethod(char* ext) { if (strcmp(ext, "a") == 0) { dllFuncationA(); } else if (strcmp(ext, "b") == 0) { dllFuncationB(); } else if (strcmp(ext, "c") == 0) { dllFuncationC(); } }
The exists(char* fileName) method checks to see if the file can be opened, then closes the file, returns true if it does; else returns false. Figured I might add that in too since it's already a long enough post. Sorry....
Reading about realloc() now... I used malloc() and free() not realloc().
Is there really a difference which way I do it? Do they both produce the same results?
I don't see any obvious problems in your createOutputFile() function, but there are several lines you don't need. For example calling free() on a NULL pointer is allowed. And if you already have a valid string, you don't need to check for a null pointer before you free it. So:
The above could be reduced to:Code:> if (!exists(source)) > { > if (source) > { > free(source); > source = NULL; > } > return; > }
Code:if (!exists(source)) { free(source); return; }The above could be reduced to:Code:> if (destination) > { > free(destination); > destination = NULL; > }
Code:free(destination);The above could be reduced to:Code:if (!exists(source)) { if (source) { free(source); source = NULL; } if (destination) { free(destination); destination= NULL; } return; }
And so forth. In addition you could add checks after each malloc(). Like here:Code:if (!exists(source)) { free(source); free(destination); return; }
Code:destination = malloc(strlen(INPUT) + strlen(ext[index]) + 1);And there's another malloc() for source which needs a check.Code:destination = malloc(strlen(INPUT) + strlen(ext[index]) + 1); if (destination == NULL) { free(source); return; }
Last edited by swoopy; 04-18-2007 at 04:30 PM.
Thanks.
Wasn't sure if I need to add the source == NULL or destination == NULL after using free(), but figured it wouldn't hurt.
I don't mind removing extra lines either. )
I'm getting the following error when I return from the JNI method.
Seems the pointer to the dll functions work and the final output is printed. I get the final.txt file and the contents are corrent.
But what is an illegal instruction 2??
Googled, but didn't understand the little info there was to offer on it.
#
# An unexpected error has been detected by HotSpot Virtual Machine:
#
# EXCEPTION_ILLEGAL_INSTRUCTION_2 (0xc000001e) at pc=0x02fdfac4, pid=3944, tid=3168
#
# Java VM: Java HotSpot(TM) Client VM (1.5.0_05-b05 mixed mode, sharing)
# Problematic frame:
# C 0x02fdfac4
#
After trying to figure out my nice error... I came up with this...
The dll is loaded, the GetProcAddress(....) returns okay. I check for a NULL return from the GetProcAddress(....)
//... load dll and blah, blah, blah....
Code:if (getOutputFile) { printf("Function loaded"); getOutputFile(); return 1; } else { printf("Function not loaded"); return 0; }
I get the right printout...
So I tried calling the method from the initDLL() where the function is loaded... To my surprise, the function works and does not crash out on the return from the initDLL() method.
All was OKAY!!
Now, I call the dll function from a function in the code... using the same code as above, still checking to see if the dll function is not NULL...
and then I called the getOutputFile(); and the function works and the output file is produced, but then I crash out on the return from that function.Code:if (getOutputFile) { printf("Function loaded"); ....... ........
So what is up with that. What would make the function work when it is originally loaded, but cannot be used in the program anywhere else or called from any other function.
??
Quick question, why have I seen some examples where the function call is in parenthesis and others are not?
(getOutputFile)();
or
getOutputFile();
Thanks!!!!!!!!
I think they're effectively the same thing, but not sure. Maybe Salem or one of the other gurus here know.
As far as you're other problem, I'm mystified. If I think of something I'll post.
By the way the realloc() idea is good. Since you're reusing the same string's, it could only make for a cleaner run.
>Now, I call the dll function from a function in the code...
I don't know if it's possible, but it would be interesting to move call to the dll function to a third place, somewhere earlier in the run, to see if it still crashes.
Rellocating ....
From the JNI method... I called initDLL(), loading the dll and functions...
then I called the getOutputFile(), which completes, and on the return from getOutputFile() to the JNI method -- it crashes.
JniMethod() --> initDll() --> returns
JniMethod() --> getOutputFile() --> returns & crashes
So then from the initDLL(), I load the dll and functions, and I call the dll function right after, the dll function works, it returns to the JNI method after the initDLL() and doesn't crash...
JniMethod() --> initDll() --> getOutputFile() --> returns
JniMethod() --> returns successfully
So then I made a third function, called test() to call the dll function... From the JNI method I called initDll(), which returns after initializes the dll and functions, then I called test() which calls the getOutputFile() which calls the dll functions, it completes the dll function, and then crashes...
JniMethod() --> initDll() --> returns
JniMethod() --> test() --> getOutputFile() --> returns & crashes
So I am totally confused...
I thought maybe it was releasing the dll ... but checked and commented out the FreeLibrary(hLib) call just incase... and didn't help.
Not a clue, but I get one of the two depending on where I call the dll function:
EXCEPTION_ACCESS_VIOLATION or
EXCEPTION_ILLEGAL_INSTRUCTION_2
??
Here's an idea. Take the getOutputFile function, copy it and create a second function. In this second function, make all your buffers fixed char arrays, and remove the dynamic allocation (calls to malloc() and free()). So source and destination would be something like:
Then try calling this second function instead of the original getOutputFile, and see what happens.Code:char source[120], destination[120];
I'm not sure where you're calling GetProcAddress, but maybe you need to call that right before you call dllFunctionA, dllFunctionB, and dllFunctionC, in your getOutputFile function, assuming you're not already.
Is it getOutputFile, or createOutputFile, or is there both?
Last edited by swoopy; 04-20-2007 at 12:13 PM.