我想更多地瞭解Runtime.InteropServices
。要做到這一點,我決定爲Excel中的一個基本的遊戲,從一個C#DLL運行。以下是遊戲的頂級C#代碼:COM互操作:C#DLL導致Excel崩潰( 「預期:要」)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
namespace ExcelEscapeGame
{
[Guid("F4810BC6-C65E-4D1B-855A-D645C7F66893")]
[ComVisible(true), InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IEscapeGame
{
[DispId(1)]
void NewGame([param: MarshalAs(UnmanagedType.I1)] byte EnemyMoveSpeed,
[param: MarshalAs(UnmanagedType.I1)] byte PlayerMoveSpeed,
[param: MarshalAs(UnmanagedType.I1)] byte EnemyCount,
[param: MarshalAs(UnmanagedType.I4)] int OuterWidth,
[param: MarshalAs(UnmanagedType.I4)] int OuterLength,
[param: MarshalAs(UnmanagedType.I4)] int BorderWidth);
[DispId(2)]
[return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_I4)]
int[,] GameMap();
}
[Guid("B937DE85-776F-4822-A3B7-A936F2043537")]
[ComVisible(true), ClassInterface(ClassInterfaceType.None)]
public class EscapeGame : IEscapeGame
{
private GameFrame GF;
private EnemyFlock TheHorde;
private Player player;
private int[,] BaseMap;
private bool Initialized = false;
public void NewGame(byte EnemyMoveSpeed, byte PlayerMoveSpeed, byte EnemyCount,
int OuterWidth, int OuterLength, int BorderWidth)
{
GF = new GameFrame(new Point(0, 0), new Point(BorderWidth, BorderWidth), OuterLength, OuterWidth);
TheHorde = new EnemyFlock(EnemyCount, EnemyMoveSpeed);
TheHorde.RandomlyPositionAtEdge(GF);
player = new Player(PlayerMoveSpeed, GF.CentrePoint());
BaseMap = GF.FrameMap();
Initialized = true;
}
public EscapeGame() { }
public EscapeGame(byte EnemyMoveSpeed, byte PlayerMoveSpeed, byte EnemyCount,
int OuterWidth, int OuterLength, int BorderWidth)
{
this.NewGame(EnemyMoveSpeed, PlayerMoveSpeed, EnemyCount,
OuterWidth, OuterLength, BorderWidth);
}
public int[,] GameMap()
{
TestInitialized();
int[,] map = CopyMap();
Point[] EnemyPositions = TheHorde.Positions();
foreach (Point p in EnemyPositions)
{
map[p.x, p.y] = (int)ColourEnum.ENEMY;
}
map[player.Position.x, player.Position.y] = (int)ColourEnum.PLAYER;
return map;
}
private int[,] CopyMap()
{
TestInitialized();
int[,] OutMap = new int[BaseMap.GetUpperBound(0) + 1, BaseMap.GetUpperBound(1) + 1];
for (int i = 0; i <= BaseMap.GetUpperBound(0); i++)
{
for (int j = 0; j <= BaseMap.GetUpperBound(1); j++)
{
OutMap[i, j] = BaseMap[i, j];
}
}
return OutMap;
}
private void TestInitialized()
{
if (!Initialized) throw new NullReferenceException("The class was not initialized");
}
}
}
我想從Excel中調用它。當我最初測試時,一切似乎都正常。現在,我已經添加了更多的類的DLL(包括上述EscapeGame類),東西似乎已經打破了,我不明白爲什麼。第一以下兩個VBA潛艇(Test
)的使用很好地工作,現在只需導致Excel立即崩潰(沒有錯誤信息),第二(Go
)只是給出「預期:以」作爲一個錯誤消息,並且不會開始運行(輔助功能就在那裏情況下,他們有相關的):
Sub Test()
Dim point As New ExcelGames.point
point.MakePoint 10, 10
Set p.Position = point
p.MoveSpeed = 2
Dim arr As Variant, pRange As Excel.Range
arr = p.Paths
Set pRange = Sheet1.Range("f10")
Application.ScreenUpdating = False
For i = 0 To UBound(arr, 1)
pRange.Offset(arr(i, 0), arr(i, 1)).Interior.ColorIndex = 5
Next i
Application.ScreenUpdating = True
End Sub
Sub Go()
Dim TheGame As New EscapeGame, p1 As New ExcelGames.point, offsetp As New ExcelGames.point
p1.MakePoint 0, 0
offsetp.MakePoint 2, 2
TheGame.NewGame 2, 2, 10, 20, 20, 2
Dim arr As Variant
arr = TheGame.GameMap()
Dim i As Long, j As Long
Application.ScreenUpdating = False
For i = 0 To UBound(arr, 1)
For j = 0 To UBound(arr, 2)
Sheet1.Cells(i + 1, j + 1).Value = arr(i, j)
Next j
Next i
Application.ScreenUpdating = True
Dim gameRange As Excel.Range
Set gameRange = Sheet1.Range(Cells(1, 1), Cells(UBound(arr, 1) + 1, UBound(arr, 2) + 1))
FormatRange gameRange
FormatConditionRange gameRange, "=" & ExcelGames.ColourEnum_INNERSQUARE, 14395790
FormatConditionRange gameRange, "=" & ExcelGames.ColourEnum_OUTERSQUARE, 15652797
FormatConditionRange gameRange, "=" & ExcelGames.ColourEnum_PLAYER, 5296274
FormatConditionRange gameRange, "=" & ExcelGames.ColourEnum_ENEMY, 8696052
End Sub
Private Sub FormatRange(ByRef xlrange As Excel.Range)
With xlrange
.Columns.ColumnWidth = _
.Columns("A").ColumnWidth/.Columns("A").Width * _
.Rows(1).Height
End With
End Sub
Private Sub FormatConditionRange(ByRef xlrange As Excel.Range, ByVal Formula As String, _
ByVal Colour As Long)
Dim FC As FormatCondition
With xlrange
Set FC = .FormatConditions.Add(xlCellValue, Operator:=xlEqual, Formula1:=Formula)
With FC
.Interior.Color = Colour
.Font.Color = Colour
.StopIfTrue = False
End With
End With
End Sub
他們的第一線執行之前無論是潛艇的失敗 - 通過在VBIDE步執行代碼,不利於亮點錯誤的原因。完全沒有錯誤 - 當我使用類從一個C#控制檯應用程序的一切DLL效果很好。 「預期:要」的含義是什麼,任何人都可以提出我做錯了什麼?