Can't release the ID3DX11Effect pointer? - graphics

I use Effect framework in my demo.
here are my defination in header file
ID3D11Buffer* m_pVertexBuffer;
ID3D11Buffer* m_pIndexBuffer;
ID3D11InputLayout* m_pInputLayout;
ID3DX11Effect* m_pFx;
ID3DX11EffectTechnique* m_pTechnique;
ID3DX11EffectMatrixVariable* m_pFxWorldViewProj;
I release them as follow
void HillsDemo::UnLoadContent()
{
if (m_pVertexBuffer) m_pVertexBuffer->Release();
if (m_pIndexBuffer) m_pIndexBuffer->Release();
if (m_pInputLayout) m_pInputLayout->Release();
if (m_pTechnique) m_pTechnique->Release();
if (m_pFx) m_pFx->Release();
}
then I run the demo,when I close the demo window, there is an error which means HillsDemo has stopped working.Why?Then I delete the lineif (m_pFx) m_pFx->Release();,there is no error. So is releasing the m_pFx make the error?
I view the documents of Effect11 https://github.com/Microsoft/FX11/wiki/Effects-11, there are on the document:
The following types are now derived from IUnknown: ID3DX11EffectType, ID3DX11EffectVariable, I3DX11EffectPass, ID3DX11EffectTechnique, ID3DX11EffectGroup. Note that these objects do not follow standard COM reference-counting rules and they are released when the parent ID3DX11Effect is released. This is mostly to simplify use of Effects 11 from managed languages.
Does it means that I should only release the m_pFx rather than release both m_pFx and m_pTechnique? Any ideas?

I assume you are using the latest version of Effects 11 from GitHub rather than the legacy DirectX SDK copy based on your reference to the project wiki.
You should really look at using ComPtr instead of raw pointers to COM objects. In the case of Effects 11, you'd just use them for ID3DX11Effect instances. You should stick with 'raw pointers' for ID3DX11EffectType, ID3DX11EffectVariable, I3DX11EffectPass, ID3DX11EffectTechnique, and ID3DX11EffectGroup. Don't bother calling Release on these raw pointers as the lifetime controlled by the ID3DX11Effect.
Something like:
Microsoft::WRL::ComPtr<ID3D11Buffer> m_pVertexBuffer;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_pIndexBuffer;
Microsoft::WRL::ComPtr<ID3D11InputLayout> m_pInputLayout;
Microsoft::WRL::ComPtr<ID3DX11Effect> m_pFx;
ID3DX11EffectTechnique* m_pTechnique;
ID3DX11EffectMatrixVariable* m_pFxWorldViewProj;
void HillsDemo::UnLoadContent()
{
m_pVertexBuffer.Reset();
m_pIndexBuffer.Reset();
m_pInputLayout.Reset();
m_pFx.Reset();
m_pTechnique = nullptr;
pFxWorldViewProj = nullptr;
}

Related

How to get a working x64 THREADSAFE Ghostscript DLL

Main context
We're actually trying to get a multi-threading version of Ghostscript x64 DLL, to make use of it through Ghostscript .NET. This component is supposed to "allow runing multiple Ghostscript instances simultaneously within a single process", but, as we have checked in our project, works fine until concurrent requests are made to the application. Same behavior can be replicated lauching same method using Tasks. The error description that raises in both cases, just when a call to the process is made until the last is being executed, is:
An error occured when call to 'gsapi_new_instance' is made: -100
Even it does no seem to be related with .NET directly, I will post a sample of our C# method code, just for contextualize.
// Define switches...
string[] switchesArray = switches.ToArray();
using (GhostscriptProcessor procesador = new GhostscriptProcessor())
{
try
{
procesador.StartProcessing(switchesArray, null);
byte[] destinationFile = System.IO.File.ReadAllBytes(destinationPath);
return destinationFile;
}
catch (Exception ex)
{
throw ex;
}
finally
{
System.IO.File.Delete(sourceFile);
}
}
THREADSAFE solution
Starting our investigation, we found this KenS's answer on this post, indicating that Ghostscript DLL must be generated with GS_THREADSAFE compiler definition.
To clarify, as we make use of Ghostscript 9.52 x64 to generate our PDFs, we need this x64 DLL compiled for Release configuration. After trying to compile Ghostscript sources on Windows 10 x64 machine, using Visual Studio Community 2017 and Visual Studio Community 2019, we finally managed to build and generate all items (only with VS Community 2019) without GS_THREADSAFE parameter, just to confirm that compilation is fine, and we check that the DLLs and executables are working. For this process we took in mind all we found in Ghostscript official documentation.
As we have no other guide to include this GS_THREADSAFE parameter, we followed the instructions given in this solution, including XCFLAGS="-DGS_THREADSAFE=1" on nmake build commands, usign this sentence for Rebuild all option:
cd .. && nmake -f psi\msvc32.mak WIN64= SBR=1 DEVSTUDIO= XCFLAGS=-DGS_THREADSAFE=1 && nmake -f psi\msvc32.mak WIN64= DEVSTUDIO= XCFLAGS=-DGS_THREADSAFE=1 bsc
This approach, rises an error during build:
Error LNK2019 unresolved external symbol errprintf_nomem referenced in
function gs_log_error File \mkromfs.obj 1
As it seems, the file mkromfs.c has a method called errprintf_nomem, which can't be found when GS_THREADSAFE is set.
Questions
1 - Is there any public release of Ghostscript that include x64 DLLs compiled to be THREADSAFE?
And, if not (that's what I'm guessing...)
2 - Is it possible to get this DLL to be THREADSAFE without changing the source code?
3- Could anyone provide, please, a step by step guide or walkthrough to build a x64 Ghostscript DLL using GS_THREADSAFE using Visual Studio (or even any other possible alternative) over Windows 10 x64?
4 - A few posts talk about people achive to manage multithreading using Ghostscript .NET. I assume this examples are all using a GS_THREADSAFE DLL... Is any other workaround we have passed?
Thank a lot in advance.
To summarize all this questions, and as a guide for future developers having this same trouble, these are the answers we've found until now:
AS #KenS mentions in his reply: "No, the Ghostscript developers don't actually build thread-safe versions of the binaries."
At this very moment, clearly not, as it has been reported on this opened bug.
As it seems to be a matter of commercial licensing support, we avoid comment on this point anymore.
Thanks again to #HABJAN. I absolutely take back what I've stated on my question, as it is possible to have Ghostscript .NET working on multi-threading scenarios. Below comes the solution we applied, in case it could be useful for someone.
Based on HABJAN example, what we have done to achieve this was to create a custom class to capture Ghostscript logging:
protected class ConsoleStdIO : Ghostscript.NET.GhostscriptStdIO
{
public ConsoleStdIO(bool handleStdIn, bool handleStdOut, bool handleStdErr) : base(handleStdIn, handleStdOut, handleStdErr)
{
}
public override void StdIn(out string input, int count)
{
char[] userInput = new char[count];
Console.In.ReadBlock(userInput, 0, count);
input = new string(userInput);
}
public override void StdOut(string output)
{
//log
}
public override void StdError(string error)
{
//log
}
}
For our previous method, we simple include a call to this class and this avoids errors when multiple tasks are executed at the same time:
// Define switches...
string[] switchesArray = switches.ToArray();
using (GhostscriptProcessor procesador = new GhostscriptProcessor())
{
try
{
procesador.StartProcessing(switchesArray, new ConsoleStdIO(true, true, true));
byte[] destinationFile = System.IO.File.ReadAllBytes(destinationPath);
return destinationFile;
}
catch (Exception ex)
{
throw ex;
}
finally
{
System.IO.File.Delete(sourceFile);
}
}
Well, it seems to me that you are asking here for technical support.
You clearly want to use Ghostscript in a commercial undertaking, indeed one might reasonably say you want an enterprise version of Ghostscript. Presumably you don't want to alter the source in order to permit you to use an open source license, because you don't want to pay for a commercial license.
With that in mind the answers to your questions are:
No, the Ghostscript developers don't actually build thread-safe versions of the binaries.
Currently, no. That's probably an oversight.
That would be a technical support question, there's no guarantee of technical support to free users, it's the one of the few areas of leverage for dual license vendors to persuade people to take up a commercial license. So I hope you will understand that I'm not going to provide that.
as far as I can see, no.

using a cli c++ object as the value of a c++ std::map

I have a code that's a mixture of standard C++ and cli/c++
And i am trying to create the following object:
std::map<std::string, System::IO::StreamWriter> streamWrite;
But it doesn't work. the compiler actually crushes when i try to build the project.
Is there a way to make it work?
Edit: my code is originally cli c++ and i am slowly converting it to native c++, and that's why i have a mixture of both native and managed objects.
I have no idea yet how to convert StreaReader and StreamWriter objects to native C++ so i am leaving this to the very end, so i n the meantime i have this "strange creature" - std::map that holds a managed object as its value.
Standard C++ things (like std::map) and managed objects do not mix out of the box. It is however possible by using GCHandle to get an intptr_t that represents a managed object and keeps it from getting garbage collected.
intptr_t GetHandle(System::Object^ obj) {
auto gch = System::Runtime::InteropServices::GCHandle::Alloc(obj);
auto ip = System::Runtime::InteropServices::GCHandle::ToIntPtr(gch);
return static_cast<intptr_t>(ip);
}
Now you have an intptr_t that represents a your object and can be freely used with native C++ code. std::map<std::string, intptr_t>
To get your object from the intptr_t:
System::IO::StreamWriter^ ToStreamWriter(intptr_t h) {
auto gch = System::Runtime::InteropServices::GCHandle::FromIntPtr(static_cast<System::IntPtr>(h));
return safe_cast<System::IO::StreamWriter^>(gch.Target);
}
The intptr_t value represents a resource the needs to be freed so it should ideally be kept in an RAII object whose destructor will convert it back to a GCHandle (see above) and Free() that. If you don't do that then the StreamWriter object will never be garbage collected and you have a heap leak.
void FreeHandle(intptr_t h) {
auto gch = System::Runtime::InteropServices::GCHandle::FromIntPtr(static_cast<System::IntPtr>(h));
gch.Free();
}
I made a whole template library to do this kind of stuff so I can use managed objects freely in native code. I like this kind of thing but I don't necessarily recommend it. I've never seen it done by anyone else, but it does work nicely once you build good tools for it.

Regression of IntelliJ IDEA 14 support for Spock Framework?

After upgrading from IDEA 13.1.x to 14.x (14.0.2 at the moment) I see the support for Spock Framework Mock() and Stub() methods got worse.
To be more specific, I mean in-line methods stubbing/mocking with closures like:
MyType stub = Stub {
myMethod() >> { /* do something */ }
}
IDEA 13 is aware of available methods for stubbed type, which is visible on the below screen shot.
size() method is not underlined. It can be navigated to, auto-completed, checked for possible argument types and so on - usual IDE stuff. The same is possible with any other List method inside of the 'stub closure'.
While IDEA 14 lacks this feature which really is a pity. The screen shot below shows it.
size() method is underlined and greyed out. IDE seems to not have a clue what's up.
The same applies to Mock { } method event if invoked with a type as an argument like Mock(MyType) { } (and Stub(MyType) { } respectively)
My question is - is it only me or that's a bug/regression? Or maybe I need to adjust some settings?
EDIT: seems it's a bug / regression. I raised a bug in youtrack. Up vote, please.
There is a bug in storage system, i.e. GDSL works itself, but state is inconsistent across IDE startups.
As a temporary solution:
Project View -> External Libraries -> spock-core
open org.spockframework.idea.spock.gdsl in Editor
wait until Notification about disabled GDSL comes out
use Activate link in the Notification
You should enable GDSL every time you start up your Idea.
This bug is fixed and the fix will be released asap.

Is the packing of structs passed in COM interfaces defined?

I'm working with a third party COM server with its own custom interface that sets and gets structs as some of its properties. As it happens I'm using C++ for the client. I've posted some representative code from the IDL file below with names changed and GUIDs removed.
Is the packing of the structure defined or is it just good fortune that my client code happens to use the same packing settings that the COM server was built with? Would it be likely to go wrong in projects where the default C++ compiler packing settings had been changed? Is there a pragma pack setting that I could use to make sure the client compiler packing settings are correct?
I can't see any packing pragmas or statements in either the IDL or the header file generated from MIDL. What would happen if the client was in C# or VB instead? Is the packing behaviour more clearly specified if called via the IDispatch mechanism?
struct MyStruct
{
int a, b;
};
[
object,
uuid( /* removed */ ),
dual,
nonextensible,
pointer_default(unique)
]
interface IVideoOutputSettings : IDispatch{
[propget, id(1), HRESULT MyProperty([out, retval] struct MyStruct* pVal);
[propput, id(1), HRESULT MyProperty([in] struct MyStruct newVal);
/* other methods */
};
The default packing is along 8-byte boundaries, according to the MIDL command line switch reference here:
/Zp switch # MSDN (MIDL Language Reference)
Other parts of your code are more likely to break first if the pack value is changed, as the IDL file is usually pre-compiled ahead of time, and it is rare that someone will deliberately alter the command line switches given to MIDL (but not so rare that someone could fiddle with the C-scope #pragma pack and forget to restore the default state).
If you have a good reason to alter the setting, you can explicitly set the packing with a pragma pack statement.
pragma Attribute # MSDN (MIDL Language Reference)
It is pretty good fortune that no party has changed any setting that would interfere with the default packing. Can it go wrong? Yes, if someone goes out of their way to change the defaults.
When using an IDL file, the details are typically compiled into a typelib (.tlb), and it is assumed that the platform are the same for both servers and clients when using the same typelib. This is suggested in the footnotes for the /Zp switch, as certain values will fail against certain non-x86 or 16-bit targets. There can also be 32bit <-> 64bit conversion cases that could cause expectations to break. Unfortunately I don't know if there are even more cases out there, but the defaults do work with minimal fuss.
C# and VB do not have any intrinsic behavior to handle information in a .tlb; instead, a tool like tlbimp is typically used to convert COM definitions into definitions usable from .NET. I can't verify whether all expectations succeed between C#/VB.NET and COM clients and servers; However, I can verify that using a specific pragma setting other than 8 will work if you reference a .tlb that was created from an IDL compiled under that setting. While I wouldn't recommend going against the default pragma pack, here are the steps to perform if you'd like a working example to use as a reference. I created a C++ ATL project and a C# project to check.
Here are the C++ side instructions.
I created an ATL project called SampleATLProject with the default settings in Visual Studio 2010, no fields changed. This should create a dll project for you.
Compiled the project to assure that the proper C-side interface files are being created (SampleATLProject_i.c and SampleATLProject_i.h).
I added an ATL Simple Object called SomeFoo to the project. Again, no defaults were altered. This creates a class called CSomeFoo that is added to your project.
Compile SampleATLProject.
I right-clicked the SampleATLProject.idl file, then under the MIDL settings, set the Struct Member Alignment to 4 bytes (/Zp4).
Compile SampleATLProject.
I altered the IDL to add a struct definition called 'BarStruct'. This entailed adding a C-style struct definition with the MIDL uuid attribute, and an entry in library section referencing the struct definition. See snippet below.
Compile SampleATLProject.
From the Class View, I right-clicked on ISomeFoo and added a method called FooIt, that takes a struct BarStruct as an [in] parameter called theBar.
Compile SampleATLProject.
In SomeFoo.cpp, I added some code to print out the size of the struct and throw up a Message Box containing the details.
Here is my IDL for the ATL project.
import "oaidl.idl";
import "ocidl.idl";
[uuid(D2240D8B-EB97-4ACD-AC96-21F2EAFFE100)]
struct BarStruct
{
byte a;
int b;
byte c;
byte d;
};
[
object,
uuid(E6C3E82D-4376-41CD-A0DF-CB9371C0C467),
dual,
nonextensible,
pointer_default(unique)
]
interface ISomeFoo : IDispatch{
[id(1)] HRESULT FooIt([in] struct BarStruct theBar);
};
[
uuid(F15B6312-7C46-4DDC-8D04-9DEA358BD94B),
version(1.0),
]
library SampleATLProjectLib
{
struct BarStruct;
importlib("stdole2.tlb");
[
uuid(930BC9D6-28DF-4851-9703-AFCD1F23CCEF)
]
coclass SomeFoo
{
[default] interface ISomeFoo;
};
};
Inside the CSomeFoo class, here is the implementation for FooIt().
STDMETHODIMP CSomeFoo::FooIt(struct BarStruct theBar)
{
WCHAR buf[1024];
swprintf(buf, L"Size: %d, Values: %d %d %d %d", sizeof(struct BarStruct),
theBar.a, theBar.b, theBar.c, theBar.d);
::MessageBoxW(0, buf, L"FooIt", MB_OK);
return S_OK;
}
Next, on the C# side:
Go to the debug or desired output directory for SampleATLProject and run tlbimp.exe on the .tlb file generated as part of the C++ project output. The following worked for me:
tlbimp SampleATLProject.tlb /out:Foo.dll /namespace:SampleATL.FooStuff
Next, I created a C# console application, and added a reference to Foo.dll to the project.
In the References folder, go to the Properties for Foo and turn off Embed Interop Types by setting it to false.
I added a using statement to reference the namespace SampleATL.FooStuff as given to tlbimp, added the [STAThread] attribute to Main() (the COM apartment models have to match for in-proc consumption), and added some code to call the COM component.
Tlbimp.exe (Type Library Importer) # MSDN
Here is the source code for that console app.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SampleATL.FooStuff;
namespace SampleATLProjectConsumer
{
class Program
{
[STAThread]
static void Main(string[] args)
{
BarStruct s;
s.a = 1;
s.b = 127;
s.c = 255;
s.d = 128;
ISomeFoo handler = new SomeFooClass();
handler.FooIt(s);
}
}
}
Finally, it runs and I get a modal popup with the following string displayed:
Size: 12, Values: 1 127 255 128
To be sure that a pragma pack change can be made (as 4/8 byte packing are the most common alignments used), I followed these steps to change it to 1:
I returned to the C++ project, went to the properties for SampleATLProject.idl and changed the Struct Member Alignment to 1 (/Zp1).
Recompile SampleATLProject
Run tlbimp again with the updated .tlb file.
A warning icon will appear on the .NET File Reference to Foo, but may disappear if you click on the reference. If it doesn't, you can remove and re-add the reference to the C# console project to be sure it is using the new updated version.
I ran it from here and got this output:
Size: 12, Values: 1 1551957760 129 3
That's weird. But, if we forcefully edit the C-level pragma in SampleATLProject_i.h, we get the correct output.
#pragma pack(push, 1)
/* [uuid] */ struct DECLSPEC_UUID("D2240D8B-EB97-4ACD-AC96-21F2EAFFE100") BarStruct
{
byte a;
int b;
byte c;
byte d;
} ;
#pragma pack(pop)
SampleATLProject is recompiled here, no changes to the .tlb or .NET project, and we get the following:
Size: 7, Values: 1 127 255 128
Regarding IDispatch, it depends on whether your client is late-bound. Late-bound clients have to parse the type information side of IDispatch and discern the proper definitions for non-trivial types. The documentation for ITypeInfo and TYPEATTR suggests that it is possible, given that the cbAlignment field provides the information necessary. I suspect most will never alter or go against the defaults, as this would be tedious to debug if things went wrong or if the pack expectations had to change between versions. Also, structures are not typically supported by many scripting clients that can consume IDispatch. One can frequently expect that only the types governed by the IDL oleautomation keyword are supported.
IDispatch interface # MSDN
IDispatch::GetTypeInfo # MSDN
ITypeInfo interface # MSDN
TYPEATTR structure # MSDN
oleautomation keyword # MSDN
Yes, structs are a problem in COM. If you use IUnknown based interfaces then you'll have to roll the dice with proper compiler settings. Few reasons to change the default.
If you use COM Automation then you have to declare the struct with a typedef in the .IDL. So that the client code can use IRecordInfo to access the structure properly, guided by the type library info. All you have to do is ensure that your compiler's /Zp setting matches midl.exe's /Zp setting. Not hard to do.
You sail around the problem entirely by realizing that any structure can be described by an interface with properties. Now it doesn't matter.

Starting a method in another thread C++

I'm having trouble finding out how to run a method in a seperate thread in C++ (using Visual C++ 2008), I've tried a number of ways to do this but none of them so far have been successful.
I'm very new to C++ but a fairly experienced programmer in Java, but have been given a task to fix some bugs in an old C++ application. The program uses an object called 'Mpeg' to control packetising and depackitising an Mpeg file. After setting up an Mpeg object properly, mpeg.Depacketise needs to be called, which then runs the method DepacketiseInputFile().
I've tried to make DepacketiseInputFile() run in a seperate thread by both using _beginthread and the System::Threading::Thread object using
Thread^ th = gcnew Thread(gcnew ThreadStart(DepacketiseInputFile));
however this returns the errors
using &Mpeg::Depacketise gives the error
when using _beginthread the code I tried was
However with this I constantly had trouble getting the arguments correct, with errors like
cropping up.
Is there any simple way to do this that anyone can reccomend? I've spent a few days playing around with this but seem to be getting nowhere :(
Any help would be greatly appreciated.
Cheers.
What kind of type is Mpeg? What kind of method is DepacketiseInputFile?
If it's a regular unmanaged, C++ class, then use _beginthread, but you have to make DepacketiseInputFile a static. It cannot take a member function.
Also, don't call DepacketiseInputFile with DepacketiseInputFile(), pass it in with
&Mpeg::DepacketiseInputFile
You should use the void* you get to pass it to pass in a pointer to the Mpeg object (and then cast it back).
If you want to use ThreadStart, then Mpeg needs to be a managed class.
EDIT: If you want to make DepacketiseInputFile, but it needs to access the object, then you use the void* argument to pass in a pointer.
So in the .h:
void DepacketiseInputFileMember();
static void DepacketiseInputFile(void *thisObj);
Your code goes in DepacketiseInputFileMember(), and write DepacketiseInputFile like this:
void Mpeg::DepacketiseInputFile(void *thisObj)
{
Mpeg* mpeg = reinterpret_cast<Mpeg*>(thisObj);
mpeg->DepacketiseInputFileMember();
}
When you call _beginthread, use this
_beginnthread(&Mpeg::DepacketiseInputFile, (unsigned)0, anMpegObjectPointer);
where anMpegObjectPointer is a pointer to an object of type Mpeg. You have to make sure the lifetime of the object is longer than it would be needed in the thread.
Forgive my syntax, I am writing this in a textarea, not Visual Studio
Change
_beginthread(DepacketiseInputFile(), (unsigned)0, (void *)NULL);
to
_beginthread(DepacketiseInputFile, (unsigned)0, (void *)NULL);
You wanna pass the address of the function to run (DepacketiseInputFile) and not its return value of that function (which is what you get from DepacketiseInputFile()).
I'm assuming DepacketiseInputFile is declared as void DepacketiseInputFile(void*), and is not a non-static member function of some class. Otherwise, the types won't match even when you do remove the brackets.

Resources