Evan Wallace Posted August 12, 2008 Share Posted August 12, 2008 Ok, I know this is an odd request, but here it goes... I need to use C++, not C#, because I need to use a JPEG library in C. It is supposed to work because of Common Language Runtime. I have tried to create two identical code samples in both C# and C++, but the C# one works and the C++ one only works sometimes. It works on my laptop but not on my desktop, and both have the most recent version (3.35?). If you guys don't do C++ at all, just say so and I'll look elsewhere, but I just thought I'd try. Here is the C# version: using System; using System.IO; using PaintDotNet; using PaintDotNet.Data; using System.Collections.Generic; using System.Text; using System.Drawing; using System.Drawing.Imaging; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Resources; [assembly] [assembly] [assembly] [assembly] [assembly] [assembly] [assembly] [assembly] [assembly] [assembly] [assembly] [assembly] [assembly] namespace Test { public class TestFileType : FileType { public TestFileType() : base("Text Document", FileTypeFlags.SupportsLoading | FileTypeFlags.SupportsSaving, new String[] { ".txt" } ) { StreamWriter file = new StreamWriter(File.Open("C:\\test.log", FileMode.Append)); file.WriteLine("TestFileType::TestFileType() - C#"); file.Close(); } protected override Document OnLoad(Stream input) { StreamWriter file = new StreamWriter(File.Open("C:\\test.log", FileMode.Append)); file.WriteLine("TestFileType::OnLoad() - C#"); file.Close(); return new Document(100, 100); } protected override void OnSave(Document input, Stream output, SaveConfigToken token, Surface scratchSurface, ProgressEventHandler callback) { StreamWriter file = new StreamWriter(File.Open("C:\\test.log", FileMode.Append)); file.WriteLine("TestFileType::OnSave() - C#"); file.Close(); } }; public class TestFileTypeFactory : IFileTypeFactory { public FileType[] GetFileTypeInstances() { StreamWriter file = new StreamWriter(File.Open("C:\\test.log", FileMode.Append)); file.WriteLine("TestFileTypeFactory::GetFileTypeInstances() - C#"); file.Close(); return new FileType[] { new TestFileType() }; } }; } Here is the C++ version: using namespace System; using namespace System::IO; using namespace PaintDotNet; using namespace PaintDotNet::Data; using namespace System::Collections::Generic; using namespace System::Text; using namespace System::Drawing; using namespace System::Drawing::Imaging; using namespace System::Reflection; using namespace System::Runtime::CompilerServices; using namespace System::Runtime::InteropServices; using namespace System::Resources; [assembly]; [assembly]; [assembly]; [assembly]; [assembly]; [assembly]; [assembly]; [assembly]; [assembly]; [assembly]; [assembly]; [assembly]; [assembly]; namespace Test { public ref class TestFileType : FileType { public: static array^ extensions = gcnew array { ".txt" }; TestFileType() : FileType("Text Document", FileTypeFlags::SupportsLoading | FileTypeFlags::SupportsSaving, extensions ) { StreamWriter^ file = gcnew StreamWriter(File::Open("C:\\test.log", FileMode::Append)); file->WriteLine("FileType::TestFileType() - C++"); file->Close(); } protected: virtual Document^ OnLoad(Stream^ input) override { StreamWriter^ file = gcnew StreamWriter(File::Open("C:\\test.log", FileMode::Append)); file->WriteLine("FileType::OnLoad() - C++"); file->Close(); return gcnew Document(100, 100); } virtual void OnSave(Document^ input, Stream^ output, SaveConfigToken^ token, Surface^ scratchSurface, ProgressEventHandler^ callback) override { StreamWriter^ file = gcnew StreamWriter(File::Open("C:\\test.log", FileMode::Append)); file->WriteLine("FileType::OnSave() - C++"); file->Close(); } }; public ref class TestFileTypeFactory : IFileTypeFactory { public: virtual array^ GetFileTypeInstances() { StreamWriter^ file = gcnew StreamWriter(File::Open("C:\\test.log", FileMode::Append)); file->WriteLine("TestFileTypeFactory::GetFileTypeInstances() - C++"); file->Close(); return gcnew array { gcnew TestFileType() }; } }; } The code logs every function to C:\test.log. When I test both plugins, C:\test.log only contains: TestFileTypeFactory::GetFileTypeInstances() - C# TestFileType::TestFileType() - C# I was thinking that since TestFileTypeFactory::GetFileTypeInstances wasn't called, that: virtual array^ GetFileTypeInstances() isn't the right translation for: public FileType[] GetFileTypeInstances() or maybe there is an exception thrown in the Paint.NET source that is not reported, but I don't know. Any ideas? Quote Link to comment Share on other sites More sharing options...
Rick Brewster Posted August 12, 2008 Share Posted August 12, 2008 Hmm I haven't used managed C++ or C++/CLI ... what happens if you look at the compiled DLL with Reflector? You can probably set it to C# mode for its disassembly which should help with translation. http://www.aisto.com/roeder/dotnet/ Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
Evan Wallace Posted August 12, 2008 Author Share Posted August 12, 2008 Reflector looks like a great tool, but all of the decompiled functions look identical. I have a hunch that it isn't strictly a problem with the assembly, because it loads fine on some computers... Apparently Paint.NET silently ignores loading errors in release builds: foreach (Type type in fileTypeFactories) { ConstructorInfo ci = type.GetConstructor(System.Type.EmptyTypes); IFileTypeFactory factory; try { factory = (IFileTypeFactory)ci.Invoke(null); } catch (Exception) { #if DEBUG throw; #else continue; #endif } FileType[] fileTypes; try { fileTypes = factory.GetFileTypeInstances(); } catch (Exception) { #if DEBUG throw; #else continue; #endif } if (fileTypes != null) { foreach (FileType fileType in fileTypes) { allFileTypes.Add(fileType); } } } So I guess I'll never know why...unless there is some way to get a debug version of Paint.NET Quote Link to comment Share on other sites More sharing options...
Andrew D Posted August 12, 2008 Share Posted August 12, 2008 Mabye because people don't have the libjpeg libary? Quote Link to comment Share on other sites More sharing options...
I Like Pi Posted August 12, 2008 Share Posted August 12, 2008 So I guess I'll never know why...unless there is some way to get a debug version of Paint.NET Try copying PDN's file type code and executing that by itself. Quote Link to comment Share on other sites More sharing options...
Evan Wallace Posted August 13, 2008 Author Share Posted August 13, 2008 I finally figured it out. Gahh that took forever! I did write a loader using the Paint.NET source code and I got the error: Could not load file or assembly 'test_cpp, Version=1.0.3146.28511, Culture=neutral, PublicKeyToken=null' or one of its dependencies. This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem. (Exception from HRESULT: 0x800736B1) That led me here, which said that you have to: Copy everything on your computer from: C:\Program Files\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.CRT To here on the computer where it is not working: C:\Program Files\Paint.NET\FileTypes\Microsoft.VC90.CRT Finally works... looks like Visual C++ Express is not backwards-compatible, and Microsoft.VC90.CRT is installed in a IE7 update or something... anyway, thanks for your help! Quote Link to comment Share on other sites More sharing options...
pyrochild Posted August 13, 2008 Share Posted August 13, 2008 ...weird... Quote ambigram signature by Kemaru [i write plugins and stuff] If you like a post, upvote it! Link to comment Share on other sites More sharing options...
Andrew D Posted August 13, 2008 Share Posted August 13, 2008 So basically, you need Visual Studio. Oh well, the Express version is free. Quote Link to comment Share on other sites More sharing options...
Zagna Posted August 13, 2008 Share Posted August 13, 2008 Maybe installing this might help? Microsoft Visual C++ 2008 Redistributable Package (x86) The MSDN article mentions this as the first step? moooo.... Quote Link to comment Share on other sites More sharing options...
Evan Wallace Posted August 15, 2008 Author Share Posted August 15, 2008 Yeah I considered using the Microsoft Visual C++ 2008 Redistributable Package but I don't know if there is an uninstall option, and I like to know what I am doing to my system. If you ever want to stop using my plugin, all you have to do is delete it and the Microsoft.VC90.CRT folder instead of leaving those files who knows where on your HD. Personal preference I guess... Quote Link to comment Share on other sites More sharing options...
Zagna Posted August 15, 2008 Share Posted August 15, 2008 The redistributable packages all appear in the Control Panel Applications menu, even different versions separately. Uninstalling is as simple as with other programs, on my comp atleast. Quote Link to comment Share on other sites More sharing options...
Rick Brewster Posted August 16, 2008 Share Posted August 16, 2008 A lot of other software uses the version 9 C-runtime redistributable. It's no big deal to have it installed on the system; it's not like it's a service running in the background or anything. Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.