Lazarus resource - Using a resource leads to an error in linking - resources

I searched around but found not any solution, so I try here:
I want to integrate images (I did it with delphi before in this way) that are used by my program and load them at runtime.
My idea was to
1.) create a resource file with
lazres <resourcename> <imagename>
2.) include the resource file in the source
{$R <resourcename>}
3.) compile
Result:
Unable to find file "Debug: Trying to open file /medi/media/work/src.hg/ylazlib/test/test.src/libtest6.lpr".
The filename above is the project source and should be found.
I found out that this error almost alwas results from invalid resource files.
But the message should be explaining the problem in a better manner.
If I rename the resource file ( so it can not be found by linker) I get a 'correct' error message. In this case the unit that requires the resource is opened and the message states that the resource file can not be opened.
So what am I doing wrong here?
(I also tried to insert images in different format to the resource - so the image itself may not the problem)
any help apreciated - Thanks in advance
Note: OS: debian sid [fpc 2.6.4] Lazarus SVN

The procedure to follow is a bit different than in Delphi. As explained here, you have to
add LResources to the uses clause.
include the res file produced by Lazres in the initialization section.
uses {$I myRes} rather than {$R myRes}.
a quick test with
console lzares cmd:
C:\Users\me\Desktop\temp>lazres res.res project1.lpr=blah
source code:
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,LResources;
type
TForm1 = class(TForm)
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
initialization
{$I res.res}
end.
compiles and runs fine. Then later this can be a bit tricky to load the res if they are raw data but for pictures it's quite straightforward, cf the example in the previous link.

Related

How to use threads in lazarus?

I'm developping a multithread application using Lazarus. As i know, i have to add the class "cthreads" to uses clause, and define it in "ifdef usesCthreads", so here is the relevant part of the code:
unit Unit2;
{$mode objfpc}{$H+}
{$IFDEF usesCthreads}
Cthreads;
{$ENDIF}
interface
uses Forms, Classes, SysUtils, SyncObjs, Math, IdHttp,DateUtils,Dialogs,
ComCtrls, IdHashMessageDigest,idHash,IdComponent, cthreads;
There was no compilation error, but the form is not created because I'm having this message right after compilation: 'Run Error(211)' , plus the assembly window is showing: Cthreads_init(127).
I guess something is wrong with my code, so what is it?
Thanks for your replies.

Delphi pass string to procedure gets an access violation error

I am currently trying to create a test procedure and pass it a string. And the function checks the string for equivalence. The problem is that when the test runs, I get a access violation error of EAccessViolation on the string that I pass inside the Procedure. I understand that this is a memory declaration problem but I am not sure how to fix it.
Here is my code:
Declare
TestTForm1 = class(TTestCase)
strict private
FForm1: TForm1;
public
procedure SetUp; override;
procedure TearDown; override;
published
procedure TestCompareListBoxToFile(Method : String);
end;
Call
TestCompareListBoxToFile('Save');
Procedure
procedure TestTForm1.TestCompareListBoxToFile(Method : String);
begin
Check('Save' = Method,'they dont match');
end;
I am new to delphi so if there is anything I am missing, please let me know. please be specific in the response. Thank you.
That code is called by the unit test runner. It uses RTTI to find published methods whose names begin with 'Test'. On the face of it, this appears to be a DUnit test case.
The runner expects a procedure that accepts no parameters, and calls the method as such. You on the other hand, provide a method that does require a parameter. A parameter that is not provided. Hence the runtime error.
Now, somewhere in your code you say that you are calling the method like this:
TestCompareListBoxToFile('Save');
But that's just not how tests are invoked. Tests are invoked by the runner which uses RTTI to do so. If you attempt to call the function as well, that's just wrong.
You must declare your method like this:
procedure TestCompareListBoxToFile;
You probably need to go back to the documentation and examples for the unit test framework and learn how to design your test case to be able to accept parameters. In fact, before even doing that, I suggest you go right back to basics and make sure you fully understand how the runner discovers your tests and then runs them.

Using IDispatchImpl with an Unregistered Interface in an MFC+ATL EXE

I started the project as an MFC Application (for the GUI..), and later added support for ATL.
I then coded a simple ATL-COM object implementing a non registered dual interface using IDispatchImpl, with the 0xfff for Major and Minor, to tell ATL to load the TLB from the EXE.
I skip some details, but at the end, after some debugging I found that the CComTypeInfoHolder::GetTI implementation in atlcom.h was NOT trying to load the TLB from the EXE, but was searching it in the registry. Reason : a m_plibid variable was NOT corresponding to the DECLARE_LIBID macro use in my ATL::CAtlMfcModule declaration.
After some googling I found Bug: CAtlMfcModule::InitLibId() not called and added a call to InitLibId in my module CTOR.
Works fine, now.
Question: Is that a known bug? with a known fix? I am not confortable with my workaround of such an old bug. Is there another way of dealing with that?
UPDATE: additional information, as an answer states there is no bug...
IDispatchImpl Class:
By default, the IDispatchImpl class looks up the type information for
T in the registry. To implement an unregistered interface, you can use
the IDispatchImpl class without accessing the registry by using a
predefined version number. If you create an IDispatchImpl object that
has 0xFFFF as the value for wMajor and 0xFFFF as the value for wMinor,
the IDispatchImpl class retrieves the type library from the .dll file
instead of the registry.
Excerpt from CComTypeInfoHolder::GetTI Implementation in atlcom.h:
if (InlineIsEqualGUID( CAtlModule::m_libid, *m_plibid) &&
m_wMajor == 0xFFFF &&
m_wMinor == 0xFFFF ) {
TCHAR szFilePath[MAX_PATH];
DWORD dwFLen = ::GetModuleFileName(_AtlBaseModule.GetModuleInstance(), szFilePath, MAX_PATH);
[...]
hRes = LoadTypeLib(pszFile, &pTypeLib);
} else {
[...]
hRes = LoadRegTypeLib(*m_plibid, m_wMajor, m_wMinor, lcid, &pTypeLib);
So, it seems clear to me that there is an advertised behavior: use 0xffff for minor and major and ATL will try to load the typelib from module, not from registry, provided that your CAtlModule::m_libid is up todate. How is CAtlModule::m_libid expected to be be up to date? By using the DECLARE_LIBID macros. How does work that macro? by defining a static InitLibId function, which set up CAtlModule::m_libid.
The bug: when your module derives from ATL::CAtlMfcModule, the defined InitLibId function is NOT called (as ATL::CAtlMfcModule is not a class template)
You are correct, if you are using -1 for major/minor versions, then is is assumed that type information would be taken from the binary. This however does not work with MFC projects: DECLARE_LIBID only works up to CAtlMfcModule class but not its descendants.
A quick fix might be like this, in atlbase.h:
//class CAtlMfcModule :
// public ATL::CAtlModuleT<CAtlMfcModule>
template <typename T>
class CAtlMfcModuleT :
public ATL::CAtlModuleT<T>
and then in your project:
//class CMFCApplication1Module :
// public ATL::CAtlMfcModule
class CMFCApplication1Module :
public ATL::CAtlMfcModuleT<CMFCApplication1Module>
If you post it on MS Connect as a bug, you can leave a link here for others to go upvote the bug.

Can`t Load C++/CLI DLL resources

I'm trying just to see resource names but nothing appears.
I've made and compiled a C++/CLI (Managed) DLL in Visual Studio 2010 and added some Resource files as a test (one icon and one bitmap). I've checked with PE Explorer and the resources definitely are there.
My simple code:
Assembly asm = Assembly.LoadFrom("C:\\test.dll");
String[] res = asm.GetManifestResourceNames();
I know that the DLL is loaded because when I debug i can see all the infos in the 'asm' variable. Also i can Import data (using MEF) from the DLL.
So, the DLL has the resources and the code IS loading the assembly for sure. But why my 'res' variable always returns empty string list?
EDIT:
I've created a C# Class Library (.dll) with a resource just for a test. Now it works!! But still in my C++/CLI DLL the resources do not appear. Somehow they are in the DLL but the code cant reach it (only in the C++ DLL). Maybe it would have something to do with managed/unmanaged code, but since i'm compiling it with CLR it does not seem to be the case. Any suggestions?
SOLUTION
I've got it! Just in case someone needs.
According to these topics:
Embedding resource in a C++/CLI project
and
http://bytes.com/topic/net/answers/571530-loading-markup-xamlreader-load-resource-file#post2240705
the problem is exactly the C++/CLI thing. You have to add it in Input item under Linker tab in Project Properties. Now it seems to work fine. Thanks
I have a similar problem and your question helps me to solve it.
my project platform is C++/CLI and my DLL platform is c#.
I want to pack DLL into my executive file, hence we should put DLL in the project resource file through below steps at first:
1.copy DLL in project path.
2.put DLL name(e.g. test.dll) in below place
properties->linker->input->Embeded Managed Resource File
then we should read and use embedded DLL:
Stream^ stream = Assembly::GetExecutingAssembly()->GetManifestResourceStream("test.dll");
array<unsigned char>^ dllRawBuffer = gcnew array<unsigned char>(stream->Length);
int res = stream->Read(dllRawBuffer, 0, stream->Length);
stream->Close();
Assembly^ dllAssembly = Assembly::Load(dllRawBuffer);
System::Type^ testclass = dllAssembly->GetType("TestNamespace.TestClass");
MethodInfo^ TestMethod = testclass->GetMethod("TestMethodName");
// Create an instance.
Object^ Testobj = Activator::CreateInstance(testclass);
// Execute the method.
array<Object^>^ params = gcnew array<Object^>(2);
params[0] = 2;
params[1] = 3;
Object^ result = TestMethod->Invoke(Testobj, params);
obviously, this solution only works for managed DLLs.

Duplicate identifier 'nodeName' in jquery.d.ts

I have referenced jquery.d.ts in my TypeScript Project in Visual Studio 2012 and am getting the following error:
Error 1 Duplicate identifier
'nodeName' C:\DEV\MyProject\Scripts\JQuery\jquery.d.ts 786 2 pageMain.ts
Which leads to the following code in jquery.d.ts:
interface EventTarget {
nodeName: string;
}
I have restarted VS2012, and then again after deleting all the .sou files for the project.
I have checked all my references (includes) and found no other reference to EventTarget.
I have looked in lib.d.ts, and indeed, there is a EventTarget interface, but it does not implement nodeName.
FYI: I found two copies of lib.d.ts on my machine, and checked them both: does anyone know which one is used by the compiler? I did mods on both (changing the window.alert to window.alert2), but they had no effect.
Your jQuery.d.ts needs to be updated.
Here is a quick way to test the issue:
declare var x: EventTarget;
x.nodeName = '';
If you run this on the TypeScript Playground, you'll see that nodeName does not exist on EventTarget. Indeed, if you look at the lib.d.ts file, you'll find this:
interface EventTarget {
removeEventListener(type: string, listener: EventListener, useCapture?: bool): void;
addEventListener(type: string, listener: EventListener, useCapture?: bool): void;
dispatchEvent(evt: Event): bool;
}
However, if you run the same code within Visual Studio with Web Essentials, you'll find that nodeName does exist on EventTarget. This is because Web Essentials is using a newer version of lib.d.ts - if you disable Web Essentials, you would get the same error as you see in the Playground.
These issues will happen occasionally as the standard definitions are improved to keep up with what browsers actually support. Your definition files should be adjusted to keep in line with your development tools, with a preference to changing files such as jquery.d.ts rather than lib.d.ts.
Interesting bug, I faced same issue with className instead of nodeName
After spending sometime trying to solve the issue I found this article link in jquery.d.ts file
I am maintaining general.d.ts file to create required interface items needed.
I added the following definition to the file
interface EventTarget {
className: string;
}
Immediately I got an error message of duplicate identifier.
I kept it and saved general.d.ts, and went back to my original working file, I found the compiler passed through.
My assumption it is Web Essentials bug failing to load definitions properly.

Resources