дано: две простенькие программы, обе вызывают CreateWindowEx, в случае с C# все отрабатывает как часы, в случае Nemerle функция возвращает ошибку System can not find the file specified. Свойства обоих проектов — by default, т.е. any cpu и там и там, винда x64 семерка.
вопрос: равнозначны ли след. листинги и если да, то в чем проблема?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.ComponentModel;
namespace test2
{
class Program
{
static void Main(string[] args)
{
CreateWindowEx(0, "STATIC", "asdjflaskdfh", WindowStyles.WS_OVERLAPPEDWINDOW,
1, 1, 300, 300, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
var code = Marshal.GetLastWin32Error();
if (code != 0)
throw new Win32Exception(code);
}
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr CreateWindowEx(
WindowStylesEx dwExStyle,
string lpClassName,
string lpWindowName,
WindowStyles dwStyle,
int x,
int y,
int nWidth,
int nHeight,
IntPtr hWndParent,
IntPtr hMenu,
IntPtr hInstance,
IntPtr lpParam);
}
[Flags()]
enum WindowStyles : uint
{
WS_BORDER = 0x800000,
WS_CAPTION = 0xc00000,
WS_CHILD = 0x40000000,
WS_CLIPCHILDREN = 0x2000000,
WS_CLIPSIBLINGS = 0x4000000,
WS_DISABLED = 0x8000000,
WS_DLGFRAME = 0x400000,
WS_GROUP = 0x20000,
WS_HSCROLL = 0x100000,
WS_MAXIMIZE = 0x1000000,
WS_MAXIMIZEBOX = 0x10000,
WS_MINIMIZE = 0x20000000,
WS_MINIMIZEBOX = 0x20000,
WS_OVERLAPPED = 0x0,
WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_SIZEFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
WS_POPUP = 0x80000000u,
WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU,
WS_SIZEFRAME = 0x40000,
WS_SYSMENU = 0x80000,
WS_TABSTOP = 0x10000,
WS_VISIBLE = 0x10000000,
WS_VSCROLL = 0x200000
}
[Flags]
enum WindowStylesEx : uint
{
WS_EX_ACCEPTFILES = 0x00000010,
WS_EX_APPWINDOW = 0x00040000,
WS_EX_CLIENTEDGE = 0x00000200,
WS_EX_COMPOSITED = 0x02000000,
WS_EX_CONTEXTHELP = 0x00000400,
WS_EX_CONTROLPARENT = 0x00010000,
WS_EX_DLGMODALFRAME = 0x00000001,
WS_EX_LAYERED = 0x00080000,
WS_EX_LAYOUTRTL = 0x00400000,
WS_EX_LEFT = 0x00000000,
WS_EX_LEFTSCROLLBAR = 0x00004000,
WS_EX_LTRREADING = 0x00000000,
WS_EX_MDICHILD = 0x00000040,
WS_EX_NOACTIVATE = 0x08000000,
WS_EX_NOINHERITLAYOUT = 0x00100000,
WS_EX_NOPARENTNOTIFY = 0x00000004,
WS_EX_OVERLAPPEDWINDOW = WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE,
WS_EX_PALETTEWINDOW = WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST,
WS_EX_RIGHT = 0x00001000,
WS_EX_RIGHTSCROLLBAR = 0x00000000,
WS_EX_RTLREADING = 0x00002000,
WS_EX_STATICEDGE = 0x00020000,
WS_EX_TOOLWINDOW = 0x00000080,
WS_EX_TOPMOST = 0x00000008,
WS_EX_TRANSPARENT = 0x00000020,
WS_EX_WINDOWEDGE = 0x00000100
}
}
using Nemerle.Collections;
using Nemerle.Text;
using Nemerle.Utility;
using System;
using System.Collections.Generic;
using System.Console;
using System.Linq;
using System.Runtime.InteropServices;
using System.ComponentModel;
module Program
{
Main() : void
{
_ = CreateWindowEx(0, "STATIC", "asdjflaskdfh", WindowStyles.WS_OVERLAPPEDWINDOW,
1, 1, 300, 300, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
def code = Marshal.GetLastWin32Error();
when (code != 0)
throw Win32Exception(code);
}
[DllImportAttribute ( "User32.dll", SetLastError=true )]
extern CreateWindowEx(dwExStyle : WindowStylesEx, lpClassName : string, lpWindowName : string, dwStyle : WindowStyles,
x : int, y : int, nWidth : int, nHeight : int, hWndParent : IntPtr, hMenu : IntPtr, hInstance : IntPtr, lpParam : IntPtr) : IntPtr;
[FlagsAttribute]
enum WindowStyles : uint
{
| WS_BORDER = 0x800000
| WS_CAPTION = 0xc00000
| WS_CHILD = 0x40000000
| WS_CLIPCHILDREN = 0x2000000
| WS_CLIPSIBLINGS = 0x4000000
| WS_DISABLED = 0x8000000
| WS_DLGFRAME = 0x400000
| WS_GROUP = 0x20000
| WS_HSCROLL = 0x100000
| WS_MAXIMIZE = 0x1000000
| WS_MAXIMIZEBOX = 0x10000
| WS_MINIMIZE = 0x20000000
| WS_MINIMIZEBOX = 0x20000
| WS_OVERLAPPED = 0x0
| WS_OVERLAPPEDWINDOW = 0xCF0000
| WS_POPUP = 0x80000000u
| WS_POPUPWINDOW = 0x80880000
| WS_SIZEFRAME = 0x40000
| WS_SYSMENU = 0x80000
| WS_TABSTOP = 0x10000
| WS_VISIBLE = 0x10000000
| WS_VSCROLL = 0x200000
}
[FlagsAttribute]
enum WindowStylesEx : uint
{
| WS_EX_ACCEPTFILES = 0x00000010
| WS_EX_APPWINDOW = 0x00040000
| WS_EX_CLIENTEDGE = 0x00000200
| WS_EX_COMPOSITED = 0x02000000
| WS_EX_CONTEXTHELP = 0x00000400
| WS_EX_CONTROLPARENT = 0x00010000
| WS_EX_DLGMODALFRAME = 0x00000001
| WS_EX_LAYERED = 0x00080000
| WS_EX_LAYOUTRTL = 0x00400000
| WS_EX_LEFT = 0x00000000
| WS_EX_LEFTSCROLLBAR = 0x00004000
| WS_EX_LTRREADING = 0x00000000
| WS_EX_MDICHILD = 0x00000040
| WS_EX_NOACTIVATE = 0x08000000
| WS_EX_NOINHERITLAYOUT = 0x00100000
| WS_EX_NOPARENTNOTIFY = 0x00000004
| WS_EX_OVERLAPPEDWINDOW = 0x00000300
| WS_EX_PALETTEWINDOW = 0x00000188
| WS_EX_RIGHT = 0x00001000
| WS_EX_RIGHTSCROLLBAR = 0x00000000
| WS_EX_RTLREADING = 0x00002000
| WS_EX_STATICEDGE = 0x00020000
| WS_EX_TOOLWINDOW = 0x00000080
| WS_EX_TOPMOST = 0x00000008
| WS_EX_TRANSPARENT = 0x00000020
| WS_EX_WINDOWEDGE = 0x00000100
}
}
Здравствуйте, Visor2004, Вы писали:
V>дано: две простенькие программы, обе вызывают CreateWindowEx, в случае с C# все отрабатывает как часы, в случае Nemerle функция возвращает ошибку System can not find the file specified. Свойства обоих проектов — by default, т.е. any cpu и там и там, винда x64 семерка.
V>вопрос: равнозначны ли след. листинги и если да, то в чем проблема?
В том и дело что нет.
У Nemerle имеется баг. Игнорируется SetLastError=true !
module Program
{
[DllImport("a.dll", SetLastError=true)]
public extern F() : void;
}
ILSpy:
class Program
{
[DllImport("a.dll")]
public static extern void F();
}
Тест:
using System;
using System.Console;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Reflection;
namespace test2
{
module Program
{
[DllImport("a.dll", SetLastError=true)]
public extern F() : void;
Main() : void
{
def t = Type.GetType("test2.Program");
def f = t.GetMethod("F");
foreach (at in f.GetCustomAttributes(false))
{
| dat is DllImportAttribute => WriteLine(dat.SetLastError);
| _ => ()
}
}
}
}
False
Здравствуйте, _NN_, Вы писали:
_NN>У Nemerle имеется баг. Игнорируется SetLastError=true !
пофиг на баг, если бы окно реально создавалось, я бы даже не думал смотреть GetLastError
Здравствуйте, Visor2004, Вы писали:
V>Здравствуйте, _NN_, Вы писали:
_NN>>У Nemerle имеется баг. Игнорируется SetLastError=true !
V>пофиг на баг, если бы окно реально создавалось, я бы даже не думал смотреть GetLastError
А как вы проверяете что оно создается ?
Код падает в "when (code != 0) throw Win32Exception(code);", т.к. LastError не устанавливается в 0 из-за SetLastError = false.
Здравствуйте, Visor2004, Вы писали:
V>Здравствуйте, _NN_, Вы писали:
V>оказалось, что корень проблемы таки в игнориовании SetLastError в аттрибуте. Реально возвращался другой код ошибки.
Как я понял это баг именно с DllImportAttribute, с другими такого не происходит.
Нужно смотреть видимо в
CustomAttribute.n#L226
Здравствуйте, _NN_, Вы писали:
_NN>Как я понял это баг именно с DllImportAttribute, с другими такого не происходит.
_NN>Нужно смотреть видимо в CustomAttribute.n#L226
в иссью трекере есть этот баг? Если нет надо завести, руки дойдут и поправим.