|
he might ask, how to hide task manager process
|
|
|
|
|
He'll get the same answer.
Bastard Programmer from Hell
|
|
|
|
|
Hello!
I want to compile MuPDF as a dynamic library (dll) instead of a static library.
With the static library, everthing works fine. However, the dll version is not working. When I call, e.g.
int f = _wopen(...);
read(f, ...);
in the main app, everything works fine.
However, if
read(f, ...);
is called inside the dll, I get an assertion.
It seems to me that the file f is not known within the dll - therefore, the call to read(...) fails.
Is there any way to share the files across dll boundaries?
Alex
|
|
|
|
|
LionAM wrote: Is there any way to share the files across dll boundaries?
if your app and the DLL both are set to use the CRT in a shared library (not statically linked to the CRT), and are built to use the same version of the CRT (same compiler, CRT version, etc), it should work.
|
|
|
|
|
LionAM wrote: I get an assertion.
Which one?
LionAM wrote: the file f is not known within the dll
Where is it defined in the DLL code?
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
Thank you for the answer.
In the MuPDF sample, the file is opened with
int fd = _wopen(filename, _O_BINARY | _O_RDONLY, 0666);
The file descriptor fd is passed to a function defined within libmupdf. However, when this function tries to read the file (inside libmupdf):
read(fd, buf, bufsize)
the function fails with the assertion
---------------------------
Microsoft Visual C++ Debug Library
---------------------------
Debug Assertion Failed!
Program: p:\OLE_PDF\Debug\OLE_PDF_Test.exe
File: f:\dd\vctools\crt_bld\self_x86\crt\src\read.c
Line: 86
Expression: (_osfile(fh) & FOPEN)
I think the proble is that the libmupdf.dll "lives" in a different address space - you cannot simply assume that resources are valid inside the dll and the exe. Therefore,
I changed the MuPDF sample so that the file is opened inside the library. Now the file is read as expected.
However, there are still other (perhaps similar problems). For example, there are global variables inside libmupdf:
static fz_colorspace k_device_bgr = { -1, "DeviceRGB", 3, bgr_to_rgb, rgb_to_bgr };
fz_colorspace *fz_device_bgr = &k_device_bgr;
In the library header (which is included in the MuPDF sample), it is declared as
extern fz_colorspace *fz_device_bgr;
Inside the MuPDF sample, there is a local variable
fz_colorspace *colorspace = fz_device_bgr;
It is passed to the library. However, the function fails with an access violation when the dll tries to change a member of the colorspace struct. The problem is that fz_device_bgr has different values inside the dll and inside the sample (where it is undefinded?).
Alex
|
|
|
|
|
LionAM wrote: It is passed to the library. However, the function fails with an access violation when the dll tries to change a member of the colorspace struct. The problem is that fz_device_bgr has different values inside the dll and inside the sample (where it is undefinded?).
You can't access the main application's globals from a dll like that. They would have to be passed using a regular function call (perhaps using Get() and Set() calls).
|
|
|
|
|
Thank you for the answer.
After correcting this issue (by calling a dll function which returns the dll "version" of colorspace variable), the program does not crash any more.
However, it is still not working as expected...
I have to search further for similar issues, which becomes more difficult as I don't know where to look for the problem. I think I will debug both the statically and the dynamically linked versions simultaneously and look where they behave different...
Alex
|
|
|
|
|
For all global variables defined in the dll header, I defined a function (inside the dll) which returns the value/address of the corresponding global variable. These functions are called from the sample app instead of trying to access the global variables.
Now, the dll seems to work - I can render my pdf files.
Alex
|
|
|
|
|
If you're passing arguments by reference to/from a dll, remember that the safest thing to do is to allocate/deallocate within the same binary. In another words, don't allocate something in the dll and try to deallocate it within the executable (or the other way around).
|
|
|
|
|
Thank you for reminding that.
As far as I can see, this is already done right in the sample file.
Alex
|
|
|
|
|
How can I declare a CString reference into a generic class ?
In fact, I want to declare a CString reference that could store errors, but that CString variable to be part of external class (let's say CMyWinApp class) ... it's ilogical request ?
I try to do :
CString& m_sErrorExt;
but I get follow error :
'm_sErrorExt' : must be initialized in constructor base/member initializer list
|
|
|
|
|
Reference and const member variables must be given a value when initialized or in the constructor. Google for examples of how to resolve error C2758.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
|
|
|
|
|
You need to initialize it in the constructor.
class CMyClass
{
public:
CString m_DefaultErrorExt;
CString & m_sErrorExt;
public:
CMyClass(void) : sErrorExt(DefaultErrorExt) {}
CMyClass(CString & ExternError) : sErrorExt(ExternError) {}
};
|
|
|
|
|
With this said, this can be a dangerous practice. If the object your object is linked to, goes out of scope, your code will crash when it tries to access the reference.
I don't use this technique often. In my code, my most common usage is when I'm working with legacy code that has really bad variable names. I'll sometimes create a new variable with a meaningful name, and convert the old one to a reference, so that it's still available to code I don't intend to touch.
|
|
|
|
|
In my class, I do something that could throw into exceptions, so, I put an string reference in method paramter, like this :
BOOL CMyClass::Execute(LPCTSTR lpszParam1, CString& sError);
so, I give up the first request ... I don't know if is good ideea ...
thank you all anyway.
|
|
|
|
|
I don't understand what you're saying there.
|
|
|
|
|
Maybe it would help to understand what a reference[^] is.
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
The way you describe it, that string sounds like an object property - the last error message - so it's better and simpler to let it be a member of your class and add an accessor function for it...
class MyClass
{
public:
bool execute()
{
try
{
throw exception("Testing testing");
return true;
}
catch(exception& e)
{
m_lastError = e.what();
return false;
}
}
CString& lastError()
{
return m_lastError;
}
private:
CString m_lastError;
};
void tryIt()
{
MyClass c;
if( c.execute() )
cout << "All well" << endl;
else
cout << "MyClass.execute failed: " << c.lastError().GetString() << endl;
}
This is safer because you know the CString goes out of scope at the same time your class does, and you still have a CString reference available to use from the rest of your code exactly as before.
|
|
|
|
|
Here is what I'm going to do :
CMyClass
{
BOOL Execute(LPCTSTR lpszSQL,CString& sError);
}
BOOL CMyClass::Execute(LPCTSTR lpszSQL,CString& sError)
{
try
{
throw ....
}
catch(CException* e)
{
e->GetErrorMessage(sError.GetBufer(255),255);
sError->ReleaseBuffer();
e->Delete();
}
}
somewhere, along 'Execute' method, might have an error, and want to have method feedback and error description in one code line :
CMyClass obj;
CString sError;
if(! obj.Execute(_T("SELECT * FROM mytable"),sError))
{
MessageBox(sError);
return;
}
which in fact, it's the same thing like you describe above ...
First time, I was thinking that I could setup an external CString reference to have all posible error in CMyClass, but now I see that is not the best idea ...
But, one for another, I learn something here because of you guys, and for that I will kindly thank you.
|
|
|
|
|
Hi!
I've declared a a global structure and a static variable in a file called Common.h like this:
<pre lang="c++">
struct MenuSettings
{
int ScreenWidth;
int ScreenHeight;
}
static MenuSettings mSettings;
</pre>
I'm assigning values to ScreenWidth and ScreenHeight by reading a text file. This code is inside a file called Menu.cpp. While debugging the values of ScreenWidth and ScreenHeight inside Menu.cpp, the values are assigned correctly. I'm checking the following condition inside another file called Scroll.cpp:
<pre lang="c++">
if(mSettings.ScreenHeight >= 340)
{
}
</pre>
Here the value of "ScreenHeight" fetched from file is not coming. Instead it's coming as 0 and the if statement is bypassed. I need the correct value of ScreenHeight at Scroll.cpp. How to get it?
|
|
|
|
|
You should define the variable in just one source file, for instance:
(1) remove
pix_programmer wrote: static MenuSettings mSettings; from the header file.
(2) Put, in the Menu.cpp file the variable definition:
MenuSettings mSettings;
(3) Put in Scroll.cpp file the variable declaration as extern :
extern MenuSettings mSettings;
That's all.
Veni, vidi, vici.
|
|
|
|
|
'static', when applied to a variable definition, means you can't see the variable outside the scope of the file in which it's declared.
if you want to share a variable across CPP files, define the variable, in Menu.cpp, like this:
MenuSettings mSettings;
and then in Scroll.cpp, add the following declaration:
extern MenuSettings mSettings;
that tells the compiler to look in other files for the variable.
better yet, put extern MenuSettings mSettings; in a common header file. that way you can use the variable by simply #including the header.
also: global variables are generally not a good idea.
modified 17-Feb-12 8:35am.
|
|
|
|
|
class Base
{
public:
Base() { }
virtual void foo1() { }
virtual void foo2() { }
} ;
class Derived : public Base
{
public:
Derived() { }
void foo1() { }
void foo3() { }
} ;
int _tmain(int argc, _TCHAR* argv[])
{
Derived * d = (Derived*)new Base() ;
d->foo3() ;
return 0;
}
In above code,
1) How it is possible to call foo3() of derived class.
2) If I call d->foo1(), Base class foo1() is getting called.
I am not able to understand this. Please explain.
Regards
msr
|
|
|
|
|
d is initialized with the vtable of Base , that's the reason why Base::foo1 is called.
On the other hand it is declared as a pointer to a Derived object, hence the compiler (you fooled) calls the foo3 method.
Try
class Derived : public Base
{
int data;
public:
Derived() { data = 100;}
void foo1() { }
void foo3() { cout << data << endl;}
} ;
Too see why fooling the compiler is not a good idea.
Veni, vidi, vici.
|
|
|
|